Skip to content

Commit

Permalink
Experience/15212/submission history user flow (#15712)
Browse files Browse the repository at this point in the history
* 15212 - submission user flow

* Fixed merge conflicts
  • Loading branch information
penny-lischer authored Aug 27, 2024
1 parent 6ee8ea1 commit 1ec24e5
Show file tree
Hide file tree
Showing 7 changed files with 465 additions and 193 deletions.
8 changes: 4 additions & 4 deletions frontend-react/e2e/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ export async function tableColumnDateTimeInRange(
columnNumber: number,
fromDate: string,
toDate: string,
startTime: string,
endTime: string,
startTime?: string,
endTime?: string,
) {
let datesInRange = true;
const rowCount = await tableRows(page).count();
Expand All @@ -106,7 +106,7 @@ export async function tableColumnDateTimeInRange(
return datesInRange;
}

export function fromDateWithTime(date: string, time: string) {
export function fromDateWithTime(date: string, time?: string) {
const fromDateTime = new Date(date);

if (time) {
Expand All @@ -123,7 +123,7 @@ export function fromDateWithTime(date: string, time: string) {
return fromDateTime;
}

export function toDateWithTime(date: string, time: string) {
export function toDateWithTime(date: string, time?: string) {
const toDateTime = new Date(date);

if (time) {
Expand Down
93 changes: 72 additions & 21 deletions frontend-react/e2e/pages/authenticated/submission-history.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,86 @@
import { expect, Page } from "@playwright/test";
import { TEST_ORG_IGNORE } from "../../helpers/utils";
import { MOCK_GET_SUBMISSION_HISTORY } from "../../mocks/submissionHistory";
import { MOCK_GET_SUBMISSIONS } from "../../mocks/submissions";
import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "../BasePage";

export const URL_SUBMISSION_HISTORY = "/submissions";
export const API_GET_REPORT_HISTORY = `**/api/waters/report/**`;
export const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074";

export async function goto(page: Page) {
await page.goto(URL_SUBMISSION_HISTORY, {
waitUntil: "domcontentloaded",
});
}
export class SubmissionHistoryPage extends BasePage {
static readonly URL_SUBMISSION_HISTORY = "/submissions";

export async function gotoDetails(page: Page, id: string) {
await page.goto(`${URL_SUBMISSION_HISTORY}/${id}`, {
waitUntil: "domcontentloaded",
});
}
constructor(testArgs: BasePageTestArgs) {
super(
{
url: SubmissionHistoryPage.URL_SUBMISSION_HISTORY,
title: "ReportStream - CDC's free, interoperable data transfer platform",
heading: testArgs.page.getByRole("heading", {
name: "Submission history",
}),
},
testArgs,
);

this.addMockRouteHandlers([
// Ignore Org
this.createMockSubmissionsForOrgHandler(TEST_ORG_IGNORE, MOCK_GET_SUBMISSIONS),
this.createMockSubmissionHistoryHandler(),
]);
}

createMockSubmissionsForOrgHandler(
organization: string,
mockFileName: any,
responseStatus = 200,
): RouteHandlerFulfillEntry {
return [
`**/api/waters/org/${organization}/submissions?*`,
() => {
return {
json: mockFileName,
status: responseStatus,
};
},
];
}

export function getOrgSubmissionsAPI(org: string) {
return `**/api/waters/org/${org}/submissions?*`;
createMockSubmissionHistoryHandler(responseStatus = 200): RouteHandlerFulfillEntry {
return [
API_GET_REPORT_HISTORY,
() => {
return {
json: MOCK_GET_SUBMISSION_HISTORY,
status: responseStatus,
};
},
];
}

get filterButton() {
return this.page.getByRole("button", {
name: "Filter",
});
}

get clearButton() {
return this.page.getByRole("button", {
name: "Clear",
});
}

/**
* Error expected additionally if user context isn't admin
*/
get isPageLoadExpected() {
return super.isPageLoadExpected && this.testArgs.storageState === this.testArgs.adminLogin.path;
}
}

export async function mockGetSubmissionsResponse(page: Page, org: string, responseStatus = 200) {
const submissionsApi = getOrgSubmissionsAPI(org);
await page.route(submissionsApi, async (route) => {
const json = MOCK_GET_SUBMISSIONS;
await route.fulfill({ json, status: responseStatus });
export async function goto(page: Page) {
await page.goto(URL_SUBMISSION_HISTORY, {
waitUntil: "domcontentloaded",
});
}

Expand All @@ -41,10 +96,6 @@ export async function openReportIdDetailPage(page: Page, id: string) {
await expect(page.getByText(`Details: ${id}`)).toBeVisible();
}

export async function title(page: Page) {
await expect(page).toHaveTitle(/ReportStream - CDC's free, interoperable data transfer platform/);
}

export async function tableHeaders(page: Page) {
await expect(page.locator(".usa-table th").nth(0)).toHaveText(/Report ID/);
await expect(page.locator(".usa-table th").nth(1)).toHaveText("Date/time submitted");
Expand Down
40 changes: 40 additions & 0 deletions frontend-react/e2e/pages/authenticated/submissions-details.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { API_WATERS_REPORT } from "./report-details";
import { URL_SUBMISSION_HISTORY } from "./submission-history";
import { MOCK_GET_SUBMISSION_HISTORY } from "../../mocks/submissionHistory";
import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "../BasePage";

export const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074";
export class SubmissionsDetailsPage extends BasePage {
static readonly URL_SUBMISSIONS_DETAILS = `${URL_SUBMISSION_HISTORY}/${id}`;

constructor(testArgs: BasePageTestArgs) {
super(
{
url: SubmissionsDetailsPage.URL_SUBMISSIONS_DETAILS,
title: "ReportStream - CDC's free, interoperable data transfer platform",
},
testArgs,
);

this.addMockRouteHandlers([this.createMockSubmissionHistoryHandler(MOCK_GET_SUBMISSION_HISTORY)]);
}

createMockSubmissionHistoryHandler(mockFileName: any, responseStatus = 200): RouteHandlerFulfillEntry {
return [
`${API_WATERS_REPORT}/${id}/history`,
() => {
return {
json: mockFileName,
status: responseStatus,
};
},
];
}

/**
* Error expected additionally if user context isn't admin
*/
get isPageLoadExpected() {
return super.isPageLoadExpected && this.testArgs.storageState === this.testArgs.adminLogin.path;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
TEST_ORG_ELIMS_RECEIVER_ELIMS,
TEST_ORG_IGNORE,
TEST_ORG_UP_RECEIVER_UP,
} from "../../helpers/utils";
} from "../../../helpers/utils";
import {
applyButton,
DailyDataPage,
Expand All @@ -28,9 +28,9 @@ import {
setTime,
startDate,
startTime,
} from "../../pages/authenticated/daily-data.js";
import { URL_REPORT_DETAILS } from "../../pages/authenticated/report-details.js";
import { test as baseTest } from "../../test";
} from "../../../pages/authenticated/daily-data.js";
import { URL_REPORT_DETAILS } from "../../../pages/authenticated/report-details.js";
import { test as baseTest } from "../../../test";

const defaultStartTime = "9:00am";
const defaultEndTime = "11:00pm";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { expect } from "@playwright/test";

import {
FALLBACK_FROM_DATE_STRING,
FALLBACK_TO_DATE_STRING,
} from "../../../../src/hooks/filters/UseDateRange/UseDateRange";
import { tableColumnDateTimeInRange, tableDataCellValue, TEST_ORG_IGNORE } from "../../../helpers/utils";
import { endDate, setDate, startDate } from "../../../pages/authenticated/daily-data";
import * as submissionHistory from "../../../pages/authenticated/submission-history";
import { openReportIdDetailPage, SubmissionHistoryPage } from "../../../pages/authenticated/submission-history";
import { test as baseTest } from "../../../test";

export interface SubmissionHistoryPageFixtures {
submissionHistoryPage: SubmissionHistoryPage;
}

const test = baseTest.extend<SubmissionHistoryPageFixtures>({
submissionHistoryPage: async (
{
page: _page,
isMockDisabled,
adminLogin,
senderLogin,
receiverLogin,
storageState,
frontendWarningsLogPath,
isFrontendWarningsLog,
},
use,
) => {
const page = new SubmissionHistoryPage({
page: _page,
isMockDisabled,
adminLogin,
senderLogin,
receiverLogin,
storageState,
frontendWarningsLogPath,
isFrontendWarningsLog,
isTestOrg: true,
});
await page.goto();
await use(page);
},
});

test.describe(
"Submission history page - user flow smoke tests",
{
tag: "@smoke",
},
() => {
test.describe("admin user", () => {
test.use({ storageState: "e2e/.auth/admin.json" });

test.beforeAll(({ browserName }) => {
test.skip(browserName !== "chromium");

Check warning on line 57 in frontend-react/e2e/spec/all/authenticated/submission-history-page-user-flow.spec.ts

View workflow job for this annotation

GitHub Actions / Build Frontend React

Unexpected use of the `.skip()` annotation

Check warning on line 57 in frontend-react/e2e/spec/all/authenticated/submission-history-page-user-flow.spec.ts

View workflow job for this annotation

GitHub Actions / Release: Build Frontend (React)

Unexpected use of the `.skip()` annotation

Check warning on line 57 in frontend-react/e2e/spec/all/authenticated/submission-history-page-user-flow.spec.ts

View workflow job for this annotation

GitHub Actions / Build frontend

Unexpected use of the `.skip()` annotation
});

test.describe(`${TEST_ORG_IGNORE} org`, () => {
test("nav contains the 'Submission History' option", async ({ submissionHistoryPage }) => {
const navItems = submissionHistoryPage.page.locator(".usa-nav li");
await expect(navItems).toContainText(["Submission History"]);
});

test("has correct title", async ({ submissionHistoryPage }) => {
await expect(submissionHistoryPage.page).toHaveTitle(submissionHistoryPage.title);
await expect(submissionHistoryPage.heading).toBeVisible();
});

test("has filter", async ({ submissionHistoryPage }) => {
await expect(submissionHistoryPage.page.getByTestId("filter-container")).toBeAttached();
});

test("has footer", async ({ submissionHistoryPage }) => {
await expect(submissionHistoryPage.footer).toBeAttached();
});

test.describe("table", () => {
test.beforeEach(async ({ submissionHistoryPage }) => {
await submissionHistoryPage.page.locator(".usa-table tbody").waitFor({ state: "visible" });
});

test("table has correct headers", async ({ submissionHistoryPage }) => {
await submissionHistory.tableHeaders(submissionHistoryPage.page);
});

test("table column 'ReportId' will open the report details", async ({ submissionHistoryPage }) => {
const reportId = await tableDataCellValue(submissionHistoryPage.page, 0, 0);

await submissionHistoryPage.page.getByRole("link", { name: reportId }).click();
const responsePromise = await submissionHistoryPage.page.waitForResponse(
(res) => res.status() === 200 && res.url().includes("/history"),
);

if (responsePromise) {
await openReportIdDetailPage(submissionHistoryPage.page, reportId);
} else {
console.error("Request not received within the timeout period");
}
});

test("table has pagination", async ({ submissionHistoryPage }) => {
await expect(submissionHistoryPage.page.getByTestId("Submissions pagination")).toBeAttached();
});
});

test.describe("filter", () => {
test.describe("on 'onLoad'", () => {
test("'From' date has a default value", async ({ submissionHistoryPage }) => {
await expect(startDate(submissionHistoryPage.page)).toBeAttached();
await expect(startDate(submissionHistoryPage.page)).toHaveValue(FALLBACK_FROM_DATE_STRING);
});

test("'To' date has a default value", async ({ submissionHistoryPage }) => {
await expect(endDate(submissionHistoryPage.page)).toBeAttached();
await expect(endDate(submissionHistoryPage.page)).toHaveValue(FALLBACK_TO_DATE_STRING);
});
});

test.describe("on 'Filter'", () => {
test("with 'From' date, 'To' date", async ({ submissionHistoryPage }) => {
const fromDate = await setDate(submissionHistoryPage.page, "#start-date", 180);
const toDate = await setDate(submissionHistoryPage.page, "#end-date", 0);

// Apply button is enabled
await submissionHistoryPage.filterButton.click();
await submissionHistoryPage.page.locator(".usa-table tbody").waitFor({ state: "visible" });

// Check that table data contains the dates/times that were selected
const areDatesInRange = await tableColumnDateTimeInRange(
submissionHistoryPage.page,
1,
fromDate,
toDate,
);
expect(areDatesInRange).toBe(true);
});

test("on 'clear' resets the dates", async ({ submissionHistoryPage }) => {
await expect(startDate(submissionHistoryPage.page)).toHaveValue(FALLBACK_FROM_DATE_STRING);
await expect(endDate(submissionHistoryPage.page)).toHaveValue(FALLBACK_TO_DATE_STRING);

await setDate(submissionHistoryPage.page, "#start-date", 14);
await setDate(submissionHistoryPage.page, "#end-date", 14);

await submissionHistoryPage.clearButton.click();

await expect(startDate(submissionHistoryPage.page)).toHaveValue(FALLBACK_FROM_DATE_STRING);
await expect(endDate(submissionHistoryPage.page)).toHaveValue(FALLBACK_TO_DATE_STRING);
});
});
});
});
});
},
);
Loading

0 comments on commit 1ec24e5

Please sign in to comment.