From c29e4324cef0627eb17d9f8b162b268947f8aa82 Mon Sep 17 00:00:00 2001 From: etanb Date: Tue, 13 Aug 2024 17:12:48 -0400 Subject: [PATCH 01/17] restructure spec folder --- .../admin/receiver-status-page.spec.ts | 0 .../daily-data-details-page.spec.ts | 10 +- .../daily-data-page.spec.ts | 10 +- .../last-mile-failures-page.spec.ts | 4 +- .../message-details-page.spec.ts | 101 +++++------------ .../message-id-search-page.spec.ts | 52 +++------ .../organization-settings-page.spec.ts | 6 +- .../submission-history-page.spec.ts | 103 +++++------------- .../submissions-details-page.spec.ts | 50 +++------ .../all/{ => public/about}/about-page.spec.ts | 6 +- .../about}/our-network-page.spec.ts | 4 +- .../all/{ => public/about}/roadmap.spec.ts | 8 +- .../all/{ => public/about}/security.spec.ts | 6 +- .../getting-started/receiving-data.spec.ts | 8 +- .../getting-started/sending-data.spec.ts | 8 +- .../spec/all/{ => public}/homepage.spec.ts | 40 +++---- .../managing-your-connection-page.spec.ts | 57 +++------- .../refer-healthcare-page.spec.ts | 6 +- .../all/{ => public}/resources-page.spec.ts | 6 +- .../all/{ => public}/support-page.spec.ts | 28 ++--- 20 files changed, 158 insertions(+), 355 deletions(-) rename frontend-react/e2e/spec/all/{ => authenticated}/admin/receiver-status-page.spec.ts (100%) rename frontend-react/e2e/spec/all/{ => authenticated}/daily-data-details-page.spec.ts (96%) rename frontend-react/e2e/spec/all/{ => authenticated}/daily-data-page.spec.ts (99%) rename frontend-react/e2e/spec/all/{ => authenticated}/last-mile-failures-page.spec.ts (97%) rename frontend-react/e2e/spec/all/{ => authenticated}/message-details-page.spec.ts (63%) rename frontend-react/e2e/spec/all/{ => authenticated}/message-id-search-page.spec.ts (80%) rename frontend-react/e2e/spec/all/{ => authenticated}/organization-settings-page.spec.ts (98%) rename frontend-react/e2e/spec/all/{ => authenticated}/submission-history-page.spec.ts (74%) rename frontend-react/e2e/spec/all/{ => authenticated}/submissions-details-page.spec.ts (74%) rename frontend-react/e2e/spec/all/{ => public/about}/about-page.spec.ts (97%) rename frontend-react/e2e/spec/all/{ => public/about}/our-network-page.spec.ts (92%) rename frontend-react/e2e/spec/all/{ => public/about}/roadmap.spec.ts (90%) rename frontend-react/e2e/spec/all/{ => public/about}/security.spec.ts (95%) rename frontend-react/e2e/spec/all/{ => public}/getting-started/receiving-data.spec.ts (90%) rename frontend-react/e2e/spec/all/{ => public}/getting-started/sending-data.spec.ts (90%) rename frontend-react/e2e/spec/all/{ => public}/homepage.spec.ts (66%) rename frontend-react/e2e/spec/all/{ => public/managing-your-connection}/managing-your-connection-page.spec.ts (61%) rename frontend-react/e2e/spec/all/{ => public/managing-your-connection}/refer-healthcare-page.spec.ts (93%) rename frontend-react/e2e/spec/all/{ => public}/resources-page.spec.ts (95%) rename frontend-react/e2e/spec/all/{ => public}/support-page.spec.ts (75%) diff --git a/frontend-react/e2e/spec/all/admin/receiver-status-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts similarity index 100% rename from frontend-react/e2e/spec/all/admin/receiver-status-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts diff --git a/frontend-react/e2e/spec/all/daily-data-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts similarity index 96% rename from frontend-react/e2e/spec/all/daily-data-details-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts index 0d8930c39a7..f4da6d4a3f1 100644 --- a/frontend-react/e2e/spec/all/daily-data-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts @@ -1,9 +1,9 @@ import { expect } from "@playwright/test"; -import { tableDataCellValue } from "../../helpers/utils"; -import { detailsTableHeaders } from "../../pages/daily-data"; -import { DailyDataDetailsPage } from "../../pages/daily-data-details"; -import * as reportDetails from "../../pages/report-details"; -import { test as baseTest } from "../../test"; +import { tableDataCellValue } from "../../../helpers/utils"; +import { detailsTableHeaders } from "../../../pages/daily-data"; +import { DailyDataDetailsPage } from "../../../pages/daily-data-details"; +import * as reportDetails from "../../../pages/report-details"; +import { test as baseTest } from "../../../test"; export interface DailyDataDetailsPageFixtures { dailyDataDetailsPage: DailyDataDetailsPage; diff --git a/frontend-react/e2e/spec/all/daily-data-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts similarity index 99% rename from frontend-react/e2e/spec/all/daily-data-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts index e86e4ffb1e1..4397cbe4037 100644 --- a/frontend-react/e2e/spec/all/daily-data-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts @@ -8,8 +8,8 @@ import { tableRows, TEST_ORG_AK_RECEIVER, TEST_ORG_UP_RECEIVER_FULL_ELR, -} from "../../helpers/utils"; -import * as dailyData from "../../pages/daily-data"; +} from "../../../helpers/utils"; +import * as dailyData from "../../../pages/daily-data"; import { applyButton, DailyDataPage, @@ -30,12 +30,12 @@ import { startTime, startTimeClear, tableHeaders, -} from "../../pages/daily-data"; +} from "../../../pages/daily-data"; import { mockGetDeliveriesForOrgAlaskaResponse, mockGetDeliveriesForOrgIgnoreResponse, -} from "../../pages/report-details"; -import { test as baseTest } from "../../test"; +} from "../../../pages/report-details"; +import { test as baseTest } from "../../../test"; const defaultStartTime = "9:00am"; const defaultEndTime = "11:30pm"; diff --git a/frontend-react/e2e/spec/all/last-mile-failures-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts similarity index 97% rename from frontend-react/e2e/spec/all/last-mile-failures-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts index 8af5e5b64af..78d88094f9b 100644 --- a/frontend-react/e2e/spec/all/last-mile-failures-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; -import { tableRows } from "../../helpers/utils"; -import * as lastMileFailures from "../../pages/last-mile-failures"; +import { tableRows } from "../../../helpers/utils"; +import * as lastMileFailures from "../../../pages/last-mile-failures"; test.describe("Last Mile Failure page", () => { test.describe("not authenticated", () => { diff --git a/frontend-react/e2e/spec/all/message-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts similarity index 63% rename from frontend-react/e2e/spec/all/message-details-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts index 77291601b05..f0e902351b5 100644 --- a/frontend-react/e2e/spec/all/message-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts @@ -1,13 +1,13 @@ import { expect, test } from "@playwright/test"; import fs from "node:fs"; -import { parseFileLocation } from "../../../src/utils/misc"; -import { tableRows } from "../../helpers/utils"; -import { MOCK_GET_MESSAGE } from "../../mocks/messages"; -import * as messageDetails from "../../pages/message-details"; -import { URL_MESSAGE_DETAILS } from "../../pages/message-details"; -import * as messageIdSearch from "../../pages/message-id-search"; -import { MESSAGE_ID } from "../../pages/message-id-search"; -import { mockGetHistoryReportResponse } from "../../pages/report-details"; +import { parseFileLocation } from "../../../../src/utils/misc"; +import { tableRows } from "../../../helpers/utils"; +import { MOCK_GET_MESSAGE } from "../../../mocks/messages"; +import * as messageDetails from "../../../pages/message-details"; +import { URL_MESSAGE_DETAILS } from "../../../pages/message-details"; +import * as messageIdSearch from "../../../pages/message-id-search"; +import { MESSAGE_ID } from "../../../pages/message-id-search"; +import { mockGetHistoryReportResponse } from "../../../pages/report-details"; test.describe("Message Details Page", () => { test.describe("not authenticated", () => { test("redirects to login", async ({ page }) => { @@ -31,15 +31,11 @@ test.describe("Message Details Page", () => { test("has correct title", async ({ page }) => { await expect(page).toHaveURL(URL_MESSAGE_DETAILS); - await expect(page).toHaveTitle( - /ReportStream - CDC's free, interoperable data transfer platform/, - ); + await expect(page).toHaveTitle(/ReportStream - CDC's free, interoperable data transfer platform/); }); test("has message id section", async ({ page }) => { - await expect( - page.getByText("Message ID", { exact: true }), - ).toBeVisible(); + await expect(page.getByText("Message ID", { exact: true })).toBeVisible(); await expect(page.getByText(MESSAGE_ID)).toBeVisible(); }); @@ -49,25 +45,15 @@ test.describe("Message Details Page", () => { await expect(page.getByText("Sender:")).toBeVisible(); await expect(page.getByText(sender)).toBeVisible(); await expect(page.getByText("Incoming Report ID")).toBeVisible(); - await expect( - page.getByText(reportId, { exact: true }), - ).toBeVisible(); + await expect(page.getByText(reportId, { exact: true })).toBeVisible(); await expect(page.getByText("Date/Time Submitted")).toBeVisible(); - await expect( - page.getByText(new Date(submittedDate).toLocaleString()), - ).toBeVisible(); + await expect(page.getByText(new Date(submittedDate).toLocaleString())).toBeVisible(); await expect(page.getByText("File Location")).toBeVisible(); - await expect( - page.getByText("RECEIVE", { exact: true }), - ).toBeVisible(); - await expect( - page.getByText("ignore.ignore-simple-report"), - ).toBeVisible(); + await expect(page.getByText("RECEIVE", { exact: true })).toBeVisible(); + await expect(page.getByText("ignore.ignore-simple-report")).toBeVisible(); await expect(page.getByText("Incoming File Name")).toBeVisible(); await expect( - page.getByText( - "pdi-covid-19-d9a57df0-2702-4e28-9d80-ff8c9ec51816-20240514142655.csv", - ), + page.getByText("pdi-covid-19-d9a57df0-2702-4e28-9d80-ff8c9ec51816-20240514142655.csv"), ).toBeVisible(); }); @@ -76,9 +62,7 @@ test.describe("Message Details Page", () => { await expect(page.getByText("Receivers:")).toBeVisible(); }); - test("displays expected table headers and data", async ({ - page, - }) => { + test("displays expected table headers and data", async ({ page }) => { // include header row const rowCount = MOCK_GET_MESSAGE.receiverData.length + 1; const table = page.getByRole("table"); @@ -100,19 +84,12 @@ test.describe("Message Details Page", () => { const cols = await row.getByRole("cell").allTextContents(); expect(cols).toHaveLength(colHeaders.length); - const { - receivingOrg, - receivingOrgSvc, - createdAt, - reportId, - fileUrl, - transportResult, - } = + const { receivingOrg, receivingOrgSvc, createdAt, reportId, fileUrl, transportResult } = i === 0 ? MOCK_GET_MESSAGE.receiverData[0] - : MOCK_GET_MESSAGE.receiverData.find( - (i) => i.reportId === cols[3], - ) ?? { reportId: "INVALID" }; + : (MOCK_GET_MESSAGE.receiverData.find((i) => i.reportId === cols[3]) ?? { + reportId: "INVALID", + }); // if first row, we expect column headers. else, the data row matching the report id const expectedColContents = @@ -121,15 +98,10 @@ test.describe("Message Details Page", () => { : [ receivingOrg ?? "", receivingOrgSvc ?? "", - createdAt - ? new Date(createdAt).toLocaleString() - : "", + createdAt ? new Date(createdAt).toLocaleString() : "", reportId, - parseFileLocation( - fileUrl ?? "N/A", - ).folderLocation.toLocaleUpperCase(), - parseFileLocation(fileUrl ?? "N/A") - .sendingOrg, + parseFileLocation(fileUrl ?? "N/A").folderLocation.toLocaleUpperCase(), + parseFileLocation(fileUrl ?? "N/A").sendingOrg, parseFileLocation(fileUrl ?? "N/A").fileName, transportResult ?? "", ]; @@ -140,18 +112,11 @@ test.describe("Message Details Page", () => { } }); - test("table column 'FileName' will download file", async ({ - page, - }) => { + test("table column 'FileName' will download file", async ({ page }) => { const downloadProm = page.waitForEvent("download"); await mockGetHistoryReportResponse(page, "*"); - await tableRows(page) - .nth(0) - .locator("td") - .nth(6) - .getByRole("button") - .click(); + await tableRows(page).nth(0).locator("td").nth(6).getByRole("button").click(); const download = await downloadProm; @@ -160,9 +125,7 @@ test.describe("Message Details Page", () => { "hhsprotect-covid-19-73e3cbc8-9920-4ab7-871f-843a1db4c074.csv", ); // get and assert stats - expect( - (await fs.promises.stat(await download.path())).size, - ).toBeGreaterThan(200); + expect((await fs.promises.stat(await download.path())).size).toBeGreaterThan(200); }); }); @@ -180,11 +143,7 @@ test.describe("Message Details Page", () => { test("has alert", async ({ page }) => { await expect(page.getByTestId("alert")).toBeAttached(); - await expect( - page.getByText( - /Our apologies, there was an error loading this content./, - ), - ).toBeAttached(); + await expect(page.getByText(/Our apologies, there was an error loading this content./)).toBeAttached(); }); test("has footer", async ({ page }) => { @@ -201,11 +160,7 @@ test.describe("Message Details Page", () => { test("has alert", async ({ page }) => { await expect(page.getByTestId("alert")).toBeAttached(); - await expect( - page.getByText( - /Our apologies, there was an error loading this content./, - ), - ).toBeAttached(); + await expect(page.getByText(/Our apologies, there was an error loading this content./)).toBeAttached(); }); test("has footer", async ({ page }) => { diff --git a/frontend-react/e2e/spec/all/message-id-search-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts similarity index 80% rename from frontend-react/e2e/spec/all/message-id-search-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts index c9057d80d2a..9564d028907 100644 --- a/frontend-react/e2e/spec/all/message-id-search-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts @@ -1,13 +1,10 @@ import { expect, test } from "@playwright/test"; -import { noData, tableRows } from "../../helpers/utils"; -import { MOCK_GET_MESSAGE, MOCK_GET_MESSAGES } from "../../mocks/messages"; -import * as messageIdSearch from "../../pages/message-id-search"; -import { - MESSAGE_ID, - URL_MESSAGE_ID_SEARCH, -} from "../../pages/message-id-search"; -import { openReportIdDetailPage } from "../../pages/submission-history"; -import * as submissionHistory from "../../pages/submission-history"; +import { noData, tableRows } from "../../../helpers/utils"; +import { MOCK_GET_MESSAGE, MOCK_GET_MESSAGES } from "../../../mocks/messages"; +import * as messageIdSearch from "../../../pages/message-id-search"; +import { MESSAGE_ID, URL_MESSAGE_ID_SEARCH } from "../../../pages/message-id-search"; +import { openReportIdDetailPage } from "../../../pages/submission-history"; +import * as submissionHistory from "../../../pages/submission-history"; test.describe("Message ID Search Page", () => { test.describe("not authenticated", () => { @@ -54,9 +51,7 @@ test.describe("Message ID Search Page", () => { await expect(page.locator("footer")).toBeAttached(); }); - test("displays expected table headers and data", async ({ - page, - }) => { + test("displays expected table headers and data", async ({ page }) => { // include header row const rowCount = MOCK_GET_MESSAGES.length + 1; const table = page.getByRole("table"); @@ -64,12 +59,7 @@ test.describe("Message ID Search Page", () => { const rows = await table.getByRole("row").all(); expect(rows).toHaveLength(rowCount); - const colHeaders = [ - "Message ID", - "Sender", - "Date/time submitted", - "Incoming Report Id", - ]; + const colHeaders = ["Message ID", "Sender", "Date/time submitted", "Incoming Report Id"]; for (const [i, row] of rows.entries()) { const cols = await row.getByRole("cell").allTextContents(); expect(cols).toHaveLength(colHeaders.length); @@ -77,9 +67,7 @@ test.describe("Message ID Search Page", () => { const { messageId, sender, submittedDate, reportId } = i === 0 ? MOCK_GET_MESSAGES[0] - : MOCK_GET_MESSAGES.find( - (i) => i.reportId === cols[3], - ) ?? { reportId: "INVALID" }; + : (MOCK_GET_MESSAGES.find((i) => i.reportId === cols[3]) ?? { reportId: "INVALID" }); // if first row, we expect column headers. else, the data row matching the report id const expectedColContents = i === 0 @@ -87,9 +75,7 @@ test.describe("Message ID Search Page", () => { : [ messageId, sender ?? "", - submittedDate - ? new Date(submittedDate).toLocaleString() - : "", + submittedDate ? new Date(submittedDate).toLocaleString() : "", reportId ?? "", ]; @@ -99,9 +85,7 @@ test.describe("Message ID Search Page", () => { } }); - test("table column 'Message ID' will open message id details", async ({ - page, - }) => { + test("table column 'Message ID' will open message id details", async ({ page }) => { const messageIdCell = tableRows(page) .nth(0) .locator("td") @@ -112,17 +96,11 @@ test.describe("Message ID Search Page", () => { expect(page.locator("h1").getByText(MESSAGE_ID)).toBeTruthy(); }); - test("table column 'Incoming Report Id' will open report id details", async ({ - page, - }) => { + test("table column 'Incoming Report Id' will open report id details", async ({ page }) => { const reportId = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; - const reportIdCell = tableRows(page) - .nth(0) - .locator("td") - .nth(3) - .getByRole("link", { - name: reportId, - }); + const reportIdCell = tableRows(page).nth(0).locator("td").nth(3).getByRole("link", { + name: reportId, + }); await reportIdCell.click(); await openReportIdDetailPage(page, reportId); }); diff --git a/frontend-react/e2e/spec/all/organization-settings-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts similarity index 98% rename from frontend-react/e2e/spec/all/organization-settings-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts index e8906c66fe2..db0e119d15a 100644 --- a/frontend-react/e2e/spec/all/organization-settings-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts @@ -2,9 +2,9 @@ import { expect } from "@playwright/test"; import { readFileSync } from "node:fs"; import { join } from "node:path"; import { fileURLToPath } from "node:url"; -import { MOCK_GET_ORGANIZATION_SETTINGS_LIST } from "../../mocks/organizations"; -import { OrganizationPage } from "../../pages/organization"; -import { test as baseTest } from "../../test"; +import { MOCK_GET_ORGANIZATION_SETTINGS_LIST } from "../../../mocks/organizations"; +import { OrganizationPage } from "../../../pages/organization"; +import { test as baseTest } from "../../../test"; const __dirname = fileURLToPath(import.meta.url); diff --git a/frontend-react/e2e/spec/all/submission-history-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts similarity index 74% rename from frontend-react/e2e/spec/all/submission-history-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts index 25b3043a6d1..d1061c964d2 100644 --- a/frontend-react/e2e/spec/all/submission-history-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts @@ -1,14 +1,8 @@ import { expect, test } from "@playwright/test"; -import { - noData, - selectTestOrg, - tableDataCellValue, - tableRows, - TEST_ORG_IGNORE, -} from "../../helpers/utils"; -import * as submissionHistory from "../../pages/submission-history"; -import { openReportIdDetailPage } from "../../pages/submission-history"; +import { noData, selectTestOrg, tableDataCellValue, tableRows, TEST_ORG_IGNORE } from "../../../helpers/utils"; +import * as submissionHistory from "../../../pages/submission-history"; +import { openReportIdDetailPage } from "../../../pages/submission-history"; const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; test.describe("Submission history page", () => { @@ -28,9 +22,7 @@ test.describe("Submission history page", () => { }); test("will not load page", async ({ page }) => { - await expect( - page.getByText("Cannot fetch Organization data as admin"), - ).toBeVisible(); + await expect(page.getByText("Cannot fetch Organization data as admin")).toBeVisible(); }); test("has footer", async ({ page }) => { @@ -41,19 +33,14 @@ test.describe("Submission history page", () => { test.describe("with org selected", () => { test.beforeEach(async ({ page }) => { await selectTestOrg(page); - await submissionHistory.mockGetSubmissionsResponse( - page, - TEST_ORG_IGNORE, - ); + await submissionHistory.mockGetSubmissionsResponse(page, TEST_ORG_IGNORE); await submissionHistory.mockGetReportHistoryResponse(page); // abort all app insight calls await page.route("**/v2/track", (route) => route.abort()); await submissionHistory.goto(page); }); - test("nav contains the 'Submission History' option", async ({ - page, - }) => { + test("nav contains the 'Submission History' option", async ({ page }) => { const navItems = page.locator(".usa-nav li"); await expect(navItems).toContainText(["Submission History"]); }); @@ -63,9 +50,7 @@ test.describe("Submission history page", () => { }); test("has filter", async ({ page }) => { - await expect( - page.getByTestId("filter-container"), - ).toBeAttached(); + await expect(page.getByTestId("filter-container")).toBeAttached(); }); test.describe("table", () => { @@ -73,56 +58,35 @@ test.describe("Submission history page", () => { await submissionHistory.tableHeaders(page); }); - test("table column 'ReportId' will open the report details", async ({ - page, - }) => { - const reportId = tableRows(page) - .nth(0) - .locator("td") - .nth(0); + test("table column 'ReportId' will open the report details", async ({ page }) => { + const reportId = tableRows(page).nth(0).locator("td").nth(0); await expect(reportId).toContainText(id); await reportId.getByRole("link", { name: id }).click(); await openReportIdDetailPage(page, id); }); - test("table column 'Date/time submitted' has expected data", async ({ - page, - }) => { - expect(await tableDataCellValue(page, 0, 1)).toEqual( - "3/7/2024, 6:00:22 PM", - ); + test("table column 'Date/time submitted' has expected data", async ({ page }) => { + expect(await tableDataCellValue(page, 0, 1)).toEqual("3/7/2024, 6:00:22 PM"); }); - test("table column 'File' has expected data", async ({ - page, - }) => { - expect(await tableDataCellValue(page, 0, 2)).toEqual( - "myfile.hl7", - ); + test("table column 'File' has expected data", async ({ page }) => { + expect(await tableDataCellValue(page, 0, 2)).toEqual("myfile.hl7"); expect(await tableDataCellValue(page, 1, 2)).toEqual( "None-03c3b7ab-7c65-4174-bea7-9195cbb7ed01-20240314174050.hl7", ); }); - test("table column 'Records' has expected data", async ({ - page, - }) => { + test("table column 'Records' has expected data", async ({ page }) => { expect(await tableDataCellValue(page, 0, 3)).toEqual("1"); }); - test("table column 'Status' has expected data", async ({ - page, - }) => { - expect(await tableDataCellValue(page, 0, 4)).toEqual( - "Success", - ); + test("table column 'Status' has expected data", async ({ page }) => { + expect(await tableDataCellValue(page, 0, 4)).toEqual("Success"); }); test("table has pagination", async ({ page }) => { - await expect( - page.getByTestId("Submissions pagination"), - ).toBeAttached(); + await expect(page.getByTestId("Submissions pagination")).toBeAttached(); }); }); @@ -139,9 +103,7 @@ test.describe("Submission history page", () => { await submissionHistory.goto(page); }); - test("nav does not contain the Submissions option", async ({ - page, - }) => { + test("nav does not contain the Submissions option", async ({ page }) => { const navItems = page.locator(".usa-nav li"); await expect(navItems).not.toContainText(["Submissions"]); }); @@ -163,10 +125,7 @@ test.describe("Submission history page", () => { test.use({ storageState: "e2e/.auth/sender.json" }); test.beforeEach(async ({ page }) => { - await submissionHistory.mockGetSubmissionsResponse( - page, - TEST_ORG_IGNORE, - ); + await submissionHistory.mockGetSubmissionsResponse(page, TEST_ORG_IGNORE); await submissionHistory.mockGetReportHistoryResponse(page); await submissionHistory.goto(page); }); @@ -189,9 +148,7 @@ test.describe("Submission history page", () => { await submissionHistory.tableHeaders(page); }); - test("table column 'ReportId' will open the report details", async ({ - page, - }) => { + test("table column 'ReportId' will open the report details", async ({ page }) => { const reportId = tableRows(page).nth(0).locator("td").nth(0); await expect(reportId).toContainText(id); await reportId.getByRole("link", { name: id }).click(); @@ -199,30 +156,20 @@ test.describe("Submission history page", () => { await openReportIdDetailPage(page, id); }); - test("table column 'Date/time submitted' has expected data", async ({ - page, - }) => { - expect(await tableDataCellValue(page, 0, 1)).toEqual( - "3/7/2024, 6:00:22 PM", - ); + test("table column 'Date/time submitted' has expected data", async ({ page }) => { + expect(await tableDataCellValue(page, 0, 1)).toEqual("3/7/2024, 6:00:22 PM"); }); - test("table column 'Records' has expected data", async ({ - page, - }) => { + test("table column 'Records' has expected data", async ({ page }) => { expect(await tableDataCellValue(page, 0, 3)).toEqual("1"); }); - test("table column 'Status' has expected data", async ({ - page, - }) => { + test("table column 'Status' has expected data", async ({ page }) => { expect(await tableDataCellValue(page, 0, 4)).toEqual("Success"); }); test("table has pagination", async ({ page }) => { - await expect( - page.getByTestId("Submissions pagination"), - ).toBeAttached(); + await expect(page.getByTestId("Submissions pagination")).toBeAttached(); }); }); diff --git a/frontend-react/e2e/spec/all/submissions-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts similarity index 74% rename from frontend-react/e2e/spec/all/submissions-details-page.spec.ts rename to frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts index 7f4d76b3464..59d84e9c22a 100644 --- a/frontend-react/e2e/spec/all/submissions-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts @@ -1,8 +1,8 @@ import { expect, test } from "@playwright/test"; -import { selectTestOrg } from "../../helpers/utils"; -import * as reportDetails from "../../pages/report-details"; -import * as submissionDetails from "../../pages/submission-history"; -import { URL_SUBMISSION_HISTORY } from "../../pages/submission-history"; +import { selectTestOrg } from "../../../helpers/utils"; +import * as reportDetails from "../../../pages/report-details"; +import * as submissionDetails from "../../../pages/submission-history"; +import { URL_SUBMISSION_HISTORY } from "../../../pages/submission-history"; const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; test.describe("Submissions Details page", () => { @@ -27,9 +27,7 @@ test.describe("Submissions Details page", () => { }); test("has reportId in breadcrumb", async ({ page }) => { - await expect( - page.locator(".usa-breadcrumb ol li").nth(1), - ).toHaveText(`Details: ${id}`); + await expect(page.locator(".usa-breadcrumb ol li").nth(1)).toHaveText(`Details: ${id}`); }); test("has footer", async ({ page }) => { @@ -48,15 +46,8 @@ test.describe("Submissions Details page", () => { await submissionDetails.title(page); }); - test("breadcrumb navigates to Submission History page", async ({ - page, - }) => { - await submissionDetails.breadcrumbLink( - page, - 0, - "Submissions", - URL_SUBMISSION_HISTORY, - ); + test("breadcrumb navigates to Submission History page", async ({ page }) => { + await submissionDetails.breadcrumbLink(page, 0, "Submissions", URL_SUBMISSION_HISTORY); }); test("has footer", async ({ page }) => { @@ -74,9 +65,7 @@ test.describe("Submissions Details page", () => { }); test("has error message", async ({ page }) => { - await expect( - page.getByText(/An error has occurred./), - ).toBeAttached(); + await expect(page.getByText(/An error has occurred./)).toBeAttached(); }); test("has footer", async ({ page }) => { @@ -97,20 +86,11 @@ test.describe("Submissions Details page", () => { }); test("has reportId in breadcrumb", async ({ page }) => { - await expect( - page.locator(".usa-breadcrumb ol li").nth(1), - ).toHaveText(`Details: ${id}`); + await expect(page.locator(".usa-breadcrumb ol li").nth(1)).toHaveText(`Details: ${id}`); }); - test("breadcrumb navigates to Submission History page", async ({ - page, - }) => { - await submissionDetails.breadcrumbLink( - page, - 0, - "Submissions", - URL_SUBMISSION_HISTORY, - ); + test("breadcrumb navigates to Submission History page", async ({ page }) => { + await submissionDetails.breadcrumbLink(page, 0, "Submissions", URL_SUBMISSION_HISTORY); }); test("has footer", async ({ page }) => { @@ -127,9 +107,7 @@ test.describe("Submissions Details page", () => { }); test("has error message", async ({ page }) => { - await expect( - page.getByText(/An error has occurred./), - ).toBeAttached(); + await expect(page.getByText(/An error has occurred./)).toBeAttached(); }); test("has footer", async ({ page }) => { @@ -145,9 +123,7 @@ test.describe("Submissions Details page", () => { }); test("has error message", async ({ page }) => { - await expect( - page.getByText(/An error has occurred./), - ).toBeAttached(); + await expect(page.getByText(/An error has occurred./)).toBeAttached(); }); test("has footer", async ({ page }) => { diff --git a/frontend-react/e2e/spec/all/about-page.spec.ts b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts similarity index 97% rename from frontend-react/e2e/spec/all/about-page.spec.ts rename to frontend-react/e2e/spec/all/public/about/about-page.spec.ts index bf32d2b158b..9f965a0c34d 100644 --- a/frontend-react/e2e/spec/all/about-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts @@ -1,6 +1,6 @@ -import { scrollToFooter, scrollToTop } from "../../helpers/utils"; -import { AboutPage } from "../../pages/about"; -import { test as baseTest, expect } from "../../test"; +import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; +import { AboutPage } from "../../../../pages/about"; +import { test as baseTest, expect } from "../../../../test"; const URL_ABOUT = "/about"; diff --git a/frontend-react/e2e/spec/all/our-network-page.spec.ts b/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts similarity index 92% rename from frontend-react/e2e/spec/all/our-network-page.spec.ts rename to frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts index d8345618291..c07b65c88b1 100644 --- a/frontend-react/e2e/spec/all/our-network-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; -import * as sideNav from "../../pages/about-side-navigation"; -import * as ourNetwork from "../../pages/our-network"; +import * as sideNav from "../../../../pages/about-side-navigation"; +import * as ourNetwork from "../../../../pages/our-network"; test.describe( "Our network page", { diff --git a/frontend-react/e2e/spec/all/roadmap.spec.ts b/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts similarity index 90% rename from frontend-react/e2e/spec/all/roadmap.spec.ts rename to frontend-react/e2e/spec/all/public/about/roadmap.spec.ts index a2905db3ce5..987ddb5eaa7 100644 --- a/frontend-react/e2e/spec/all/roadmap.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts @@ -1,9 +1,9 @@ import { expect, test } from "@playwright/test"; -import * as internalLinks from "../../helpers/internal-links"; -import * as sideNav from "../../pages/about-side-navigation"; -import * as roadmap from "../../pages/roadmap"; -import { URL_ROADMAP } from "../../pages/roadmap"; +import * as internalLinks from "../../../../helpers/internal-links"; +import * as sideNav from "../../../../pages/about-side-navigation"; +import * as roadmap from "../../../../pages/roadmap"; +import { URL_ROADMAP } from "../../../../pages/roadmap"; test.describe( "Product roadmap page", diff --git a/frontend-react/e2e/spec/all/security.spec.ts b/frontend-react/e2e/spec/all/public/about/security.spec.ts similarity index 95% rename from frontend-react/e2e/spec/all/security.spec.ts rename to frontend-react/e2e/spec/all/public/about/security.spec.ts index a22b9b5c737..b1bbe565e72 100644 --- a/frontend-react/e2e/spec/all/security.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/security.spec.ts @@ -1,6 +1,6 @@ -import { scrollToFooter, scrollToTop } from "../../helpers/utils"; -import { SecurityPage } from "../../pages/security"; -import { test as baseTest, expect } from "../../test"; +import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; +import { SecurityPage } from "../../../../pages/security"; +import { test as baseTest, expect } from "../../../../test"; const URL_SECURITY = "/about/security"; diff --git a/frontend-react/e2e/spec/all/getting-started/receiving-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts similarity index 90% rename from frontend-react/e2e/spec/all/getting-started/receiving-data.spec.ts rename to frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts index 3e1eb2c7660..ef177c7c4e9 100644 --- a/frontend-react/e2e/spec/all/getting-started/receiving-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts @@ -1,7 +1,7 @@ -import site from "../../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; -import { ReceivingDataPage } from "../../../pages/getting-started/receiving-data"; -import { test as baseTest, expect } from "../../../test"; +import site from "../../../../../src/content/site.json" assert { type: "json" }; +import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; +import { ReceivingDataPage } from "../../../../pages/getting-started/receiving-data"; +import { test as baseTest, expect } from "../../../../test"; export interface ReceivingDataPageFixtures { receivingDataPage: ReceivingDataPage; diff --git a/frontend-react/e2e/spec/all/getting-started/sending-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts similarity index 90% rename from frontend-react/e2e/spec/all/getting-started/sending-data.spec.ts rename to frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts index 3e1b9f5544d..6fc94409aaf 100644 --- a/frontend-react/e2e/spec/all/getting-started/sending-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts @@ -1,7 +1,7 @@ -import site from "../../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; -import { SendingDataPage } from "../../../pages/getting-started/sending-data.js"; -import { test as baseTest, expect } from "../../../test"; +import site from "../../../../../src/content/site.json" assert { type: "json" }; +import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; +import { SendingDataPage } from "../../../../pages/getting-started/sending-data.js"; +import { test as baseTest, expect } from "../../../../test"; export interface SendingDataPageFixtures { sendingDataPage: SendingDataPage; diff --git a/frontend-react/e2e/spec/all/homepage.spec.ts b/frontend-react/e2e/spec/all/public/homepage.spec.ts similarity index 66% rename from frontend-react/e2e/spec/all/homepage.spec.ts rename to frontend-react/e2e/spec/all/public/homepage.spec.ts index 6d1b4bb9d08..a13159b12f3 100644 --- a/frontend-react/e2e/spec/all/homepage.spec.ts +++ b/frontend-react/e2e/spec/all/public/homepage.spec.ts @@ -1,11 +1,11 @@ import { expect, test } from "@playwright/test"; -import { scrollToFooter, scrollToTop } from "../../helpers/utils"; -import * as header from "../../pages/header"; -import * as homepage from "../../pages/homepage"; -import * as managingYourConnection from "../../pages/managing-your-connection"; -import * as ourNetwork from "../../pages/our-network"; -import * as security from "../../pages/security"; +import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; +import * as header from "../../../pages/header"; +import * as homepage from "../../../pages/homepage"; +import * as managingYourConnection from "../../../pages/managing-your-connection"; +import * as ourNetwork from "../../../pages/our-network"; +import * as security from "../../../pages/security"; test.describe( "Homepage", @@ -18,17 +18,11 @@ test.describe( }); test("has correct title", async ({ page }) => { - await expect(page).toHaveTitle( - /ReportStream - CDC's free, interoperable data transfer platform/, - ); + await expect(page).toHaveTitle(/ReportStream - CDC's free, interoperable data transfer platform/); }); - test("opens the Security page on 'security of your data' click", async ({ - page, - }) => { - await page - .getByRole("link", { name: "security of your data" }) - .click(); + test("opens the Security page on 'security of your data' click", async ({ page }) => { + await page.getByRole("link", { name: "security of your data" }).click(); await security.onLoad(page); // Go back to the homepage await header.clickOnHome(page); @@ -36,9 +30,7 @@ test.describe( expect(true).toBe(true); }); - test("opens the managing-your-connection page on 'our tools' click", async ({ - page, - }) => { + test("opens the managing-your-connection page on 'our tools' click", async ({ page }) => { await page.getByRole("link", { name: "our tools" }).click(); await managingYourConnection.onLoad(page); // Go back to the homepage @@ -47,12 +39,8 @@ test.describe( expect(true).toBe(true); }); - test("opens Our Network page on 'See our full network' click", async ({ - page, - }) => { - await page - .getByRole("link", { name: "See our full network" }) - .click(); + test("opens Our Network page on 'See our full network' click", async ({ page }) => { + await page.getByRole("link", { name: "See our full network" }).click(); await ourNetwork.onLoad(page); // Go back to the homepage await header.clickOnHome(page); @@ -69,9 +57,7 @@ test.describe( expect(true).toBe(true); }); - test("explicit scroll to footer and then scroll to top", async ({ - page, - }) => { + test("explicit scroll to footer and then scroll to top", async ({ page }) => { await expect(page.locator("footer")).not.toBeInViewport(); await scrollToFooter(page); await expect(page.locator("footer")).toBeInViewport(); diff --git a/frontend-react/e2e/spec/all/managing-your-connection-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts similarity index 61% rename from frontend-react/e2e/spec/all/managing-your-connection-page.spec.ts rename to frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts index 9e3d7ceabc0..cb3c02e23f4 100644 --- a/frontend-react/e2e/spec/all/managing-your-connection-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts @@ -1,25 +1,15 @@ -import { scrollToFooter, scrollToTop } from "../../helpers/utils"; -import { ManagingYourConnectionPage } from "../../pages/managing-your-connection"; -import { test as baseTest, expect } from "../../test"; +import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; +import { ManagingYourConnectionPage } from "../../../../pages/managing-your-connection"; +import { test as baseTest, expect } from "../../../../test"; const cards = [ { name: "For healthcare organizations", - links: [ - "Manage your public key", - "View your submission history", - "Login", - "contact us", - ], + links: ["Manage your public key", "View your submission history", "Login", "contact us"], }, { name: "For public health agencies", - links: [ - "Refer healthcare organizations", - "View your dashboard", - "Login", - "contact us", - ], + links: ["Refer healthcare organizations", "View your dashboard", "Login", "contact us"], }, ]; @@ -63,23 +53,16 @@ test.describe( }, () => { test("has correct title", async ({ managingYourConnectionPage }) => { - await expect(managingYourConnectionPage.page).toHaveTitle( - managingYourConnectionPage.title, - ); + await expect(managingYourConnectionPage.page).toHaveTitle(managingYourConnectionPage.title); await expect(managingYourConnectionPage.heading).toBeVisible(); }); test.describe("Quick links", () => { for (const card of cards) { - test(`should have ${card.name} links`, async ({ - managingYourConnectionPage, - }) => { - const cardHeader = managingYourConnectionPage.page.locator( - ".usa-card__header", - { - hasText: card.name, - }, - ); + test(`should have ${card.name} links`, async ({ managingYourConnectionPage }) => { + const cardHeader = managingYourConnectionPage.page.locator(".usa-card__header", { + hasText: card.name, + }); await expect(cardHeader).toBeVisible(); @@ -101,23 +84,13 @@ test.describe( await expect(managingYourConnectionPage.footer).toBeAttached(); }); - test("explicit scroll to footer and then scroll to top", async ({ - managingYourConnectionPage, - }) => { - await expect( - managingYourConnectionPage.footer, - ).not.toBeInViewport(); + test("explicit scroll to footer and then scroll to top", async ({ managingYourConnectionPage }) => { + await expect(managingYourConnectionPage.footer).not.toBeInViewport(); await scrollToFooter(managingYourConnectionPage.page); - await expect( - managingYourConnectionPage.footer, - ).toBeInViewport(); - await expect( - managingYourConnectionPage.page.getByTestId("govBanner"), - ).not.toBeInViewport(); + await expect(managingYourConnectionPage.footer).toBeInViewport(); + await expect(managingYourConnectionPage.page.getByTestId("govBanner")).not.toBeInViewport(); await scrollToTop(managingYourConnectionPage.page); - await expect( - managingYourConnectionPage.page.getByTestId("govBanner"), - ).toBeInViewport(); + await expect(managingYourConnectionPage.page.getByTestId("govBanner")).toBeInViewport(); }); }); }, diff --git a/frontend-react/e2e/spec/all/refer-healthcare-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts similarity index 93% rename from frontend-react/e2e/spec/all/refer-healthcare-page.spec.ts rename to frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts index 37421d676e4..ecf307eea36 100644 --- a/frontend-react/e2e/spec/all/refer-healthcare-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts @@ -1,6 +1,6 @@ -import { scrollToFooter, scrollToTop } from "../../helpers/utils"; -import { ReferHealthcarePage } from "../../pages/refer-healthcare"; -import { test as baseTest, expect } from "../../test"; +import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; +import { ReferHealthcarePage } from "../../../../pages/refer-healthcare"; +import { test as baseTest, expect } from "../../../../test"; export interface ReferHealthcarePageFixtures { referHealthcarePage: ReferHealthcarePage; diff --git a/frontend-react/e2e/spec/all/resources-page.spec.ts b/frontend-react/e2e/spec/all/public/resources-page.spec.ts similarity index 95% rename from frontend-react/e2e/spec/all/resources-page.spec.ts rename to frontend-react/e2e/spec/all/public/resources-page.spec.ts index ab99383c089..cc69063dbf8 100644 --- a/frontend-react/e2e/spec/all/resources-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/resources-page.spec.ts @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import * as resources from "../../pages/resources"; +import * as resources from "../../../pages/resources"; // eslint-disable-next-line playwright/no-skipped-test test.describe.skip("Developer Resources page", () => { @@ -61,9 +61,7 @@ test.describe.skip("Developer Resources page", () => { }); } - test("should redirect unauthenticated users to login page on managing public key", async ({ - page, - }) => { + test("should redirect unauthenticated users to login page on managing public key", async ({ page }) => { await page .getByRole("link", { name: "Manage your public key", diff --git a/frontend-react/e2e/spec/all/support-page.spec.ts b/frontend-react/e2e/spec/all/public/support-page.spec.ts similarity index 75% rename from frontend-react/e2e/spec/all/support-page.spec.ts rename to frontend-react/e2e/spec/all/public/support-page.spec.ts index 0948a85b187..50beb809c8c 100644 --- a/frontend-react/e2e/spec/all/support-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/support-page.spec.ts @@ -1,7 +1,7 @@ -import site from "../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop } from "../../helpers/utils"; -import { SupportPage } from "../../pages/support.js"; -import { test as baseTest, expect } from "../../test"; +import site from "../../../../src/content/site.json" assert { type: "json" }; +import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; +import { SupportPage } from "../../../pages/support.js"; +import { test as baseTest, expect } from "../../../test"; const cards = [ { @@ -58,9 +58,7 @@ test.describe("Support page", () => { }); test("Should have a way of contacting support", async ({ supportPage }) => { - const contactLink = supportPage.page - .locator(`a[href="${site.forms.contactUs.url}"]`) - .first(); + const contactLink = supportPage.page.locator(`a[href="${site.forms.contactUs.url}"]`).first(); await contactLink.scrollIntoViewIfNeeded(); await expect(contactLink).toBeVisible(); @@ -78,9 +76,7 @@ test.describe("Support page", () => { const viewAllLink = cardContainer.locator("a").last(); await viewAllLink.click(); - await expect( - supportPage.page.locator(`#${card.anchorID}`), - ).toBeVisible(); + await expect(supportPage.page.locator(`#${card.anchorID}`)).toBeVisible(); }); } @@ -89,19 +85,13 @@ test.describe("Support page", () => { await expect(supportPage.footer).toBeAttached(); }); - test("explicit scroll to footer and then scroll to top", async ({ - supportPage, - }) => { + test("explicit scroll to footer and then scroll to top", async ({ supportPage }) => { await expect(supportPage.footer).not.toBeInViewport(); await scrollToFooter(supportPage.page); await expect(supportPage.footer).toBeInViewport(); - await expect( - supportPage.page.getByTestId("govBanner"), - ).not.toBeInViewport(); + await expect(supportPage.page.getByTestId("govBanner")).not.toBeInViewport(); await scrollToTop(supportPage.page); - await expect( - supportPage.page.getByTestId("govBanner"), - ).toBeInViewport(); + await expect(supportPage.page.getByTestId("govBanner")).toBeInViewport(); }); }); }); From 98cc18cb45337a018c3bf2536b2348b5440b7b61 Mon Sep 17 00:00:00 2001 From: etanb Date: Tue, 13 Aug 2024 19:22:04 -0400 Subject: [PATCH 02/17] refactor of folder structure for pages and imports overall --- .../admin/receiver-status.ts | 150 ++++-------------- .../{ => authenticated}/daily-data-details.ts | 8 +- .../pages/{ => authenticated}/daily-data.ts | 10 +- .../{ => authenticated}/last-mile-failures.ts | 10 +- .../{ => authenticated}/message-details.ts | 2 +- .../{ => authenticated}/message-id-search.ts | 0 .../pages/{ => authenticated}/organization.ts | 20 +-- .../{ => authenticated}/report-details.ts | 10 +- .../{ => authenticated}/submission-history.ts | 35 +--- .../{ => public}/about-side-navigation.ts | 0 .../e2e/pages/{ => public/about}/about.ts | 2 +- .../pages/{ => public/about}/our-network.ts | 0 .../e2e/pages/{ => public/about}/roadmap.ts | 0 .../e2e/pages/{ => public/about}/security.ts | 2 +- .../getting-started/receiving-data.ts | 2 +- .../getting-started/sending-data.ts | 2 +- .../e2e/pages/{ => public}/header.ts | 26 +-- .../e2e/pages/{ => public}/homepage.ts | 0 .../managing-your-connection.ts | 2 +- .../refer-healthcare.ts | 2 +- .../e2e/pages/{ => public}/resources.ts | 0 .../e2e/pages/{ => public}/support.ts | 2 +- .../admin/receiver-status-page.spec.ts | 12 +- .../daily-data-details-page.spec.ts | 6 +- .../all/authenticated/daily-data-page.spec.ts | 6 +- .../last-mile-failures-page.spec.ts | 2 +- .../message-details-page.spec.ts | 10 +- .../message-id-search-page.spec.ts | 8 +- .../organization-settings-page.spec.ts | 4 +- .../submission-history-page.spec.ts | 4 +- .../submissions-details-page.spec.ts | 6 +- .../e2e/spec/all/idletimeout.spec.ts | 17 +- .../spec/all/public/about/about-page.spec.ts | 2 +- .../all/public/about/our-network-page.spec.ts | 4 +- .../e2e/spec/all/public/about/roadmap.spec.ts | 6 +- .../spec/all/public/about/security.spec.ts | 2 +- .../getting-started/receiving-data.spec.ts | 2 +- .../getting-started/sending-data.spec.ts | 2 +- .../e2e/spec/all/public/homepage.spec.ts | 10 +- .../managing-your-connection-page.spec.ts | 2 +- .../refer-healthcare-page.spec.ts | 2 +- .../spec/all/public/resources-page.spec.ts | 2 +- .../e2e/spec/all/public/support-page.spec.ts | 2 +- 43 files changed, 130 insertions(+), 266 deletions(-) rename frontend-react/e2e/pages/{ => authenticated}/admin/receiver-status.ts (75%) rename frontend-react/e2e/pages/{ => authenticated}/daily-data-details.ts (90%) rename frontend-react/e2e/pages/{ => authenticated}/daily-data.ts (97%) rename frontend-react/e2e/pages/{ => authenticated}/last-mile-failures.ts (79%) rename frontend-react/e2e/pages/{ => authenticated}/message-details.ts (76%) rename frontend-react/e2e/pages/{ => authenticated}/message-id-search.ts (100%) rename frontend-react/e2e/pages/{ => authenticated}/organization.ts (64%) rename frontend-react/e2e/pages/{ => authenticated}/report-details.ts (95%) rename frontend-react/e2e/pages/{ => authenticated}/submission-history.ts (71%) rename frontend-react/e2e/pages/{ => public}/about-side-navigation.ts (100%) rename frontend-react/e2e/pages/{ => public/about}/about.ts (85%) rename frontend-react/e2e/pages/{ => public/about}/our-network.ts (100%) rename frontend-react/e2e/pages/{ => public/about}/roadmap.ts (100%) rename frontend-react/e2e/pages/{ => public/about}/security.ts (91%) rename frontend-react/e2e/pages/{ => public}/getting-started/receiving-data.ts (88%) rename frontend-react/e2e/pages/{ => public}/getting-started/sending-data.ts (88%) rename frontend-react/e2e/pages/{ => public}/header.ts (63%) rename frontend-react/e2e/pages/{ => public}/homepage.ts (100%) rename frontend-react/e2e/pages/{ => public/managing-your-connection}/managing-your-connection.ts (91%) rename frontend-react/e2e/pages/{ => public/managing-your-connection}/refer-healthcare.ts (88%) rename frontend-react/e2e/pages/{ => public}/resources.ts (100%) rename frontend-react/e2e/pages/{ => public}/support.ts (87%) diff --git a/frontend-react/e2e/pages/admin/receiver-status.ts b/frontend-react/e2e/pages/authenticated/admin/receiver-status.ts similarity index 75% rename from frontend-react/e2e/pages/admin/receiver-status.ts rename to frontend-react/e2e/pages/authenticated/admin/receiver-status.ts index 0f69f4bb691..a937092350c 100644 --- a/frontend-react/e2e/pages/admin/receiver-status.ts +++ b/frontend-react/e2e/pages/authenticated/admin/receiver-status.ts @@ -1,18 +1,13 @@ import { expect, Locator } from "@playwright/test"; import { endOfDay, format, startOfDay, subDays } from "date-fns"; -import { RSReceiverStatus } from "../../../src/hooks/api/UseReceiversConnectionStatus/UseReceiversConnectionStatus"; +import { RSReceiverStatus } from "../../../../src/hooks/api/UseReceiversConnectionStatus/UseReceiversConnectionStatus"; import { createStatusTimePeriodData, SUCCESS_RATE_CLASSNAME_MAP, -} from "../../../src/pages/admin/receiver-dashboard/utils"; -import { DatePair, dateShortFormat } from "../../../src/utils/DateTimeUtils"; -import { createMockGetReceiverStatus } from "../../mocks/receiverStatus"; -import { - BasePage, - BasePageTestArgs, - type ResponseHandlerEntry, - type RouteHandlerFulfillEntry, -} from "../BasePage"; +} from "../../../../src/pages/admin/receiver-dashboard/utils"; +import { DatePair, dateShortFormat } from "../../../../src/utils/DateTimeUtils"; +import { createMockGetReceiverStatus } from "../../../mocks/receiverStatus"; +import { BasePage, BasePageTestArgs, type ResponseHandlerEntry, type RouteHandlerFulfillEntry } from "../../BasePage"; export interface AdminReceiverStatusPageUpdateFiltersProps { dateRange?: { @@ -90,9 +85,7 @@ export class AdminReceiverStatusPage extends BasePage { ); this.addMockRouteHandlers([this.createMockReceiverStatusHandler()]); - this.addResponseHandlers([ - this.createMockReceiverStatusResponseHandler(), - ]); + this.addResponseHandlers([this.createMockReceiverStatusResponseHandler()]); const now = new Date(); @@ -100,13 +93,8 @@ export class AdminReceiverStatusPage extends BasePage { this._timePeriodData = []; this.filterForm = this.page.getByRole("form", { name: "filter" }); - const dateRangeOverlay = this.page - .getByRole("dialog") - .locator(".usa-modal-overlay"); - const dateRangeDefaultValue = [ - startOfDay(subDays(now, 2)), - endOfDay(now), - ] as DatePair; + const dateRangeOverlay = this.page.getByRole("dialog").locator(".usa-modal-overlay"); + const dateRangeDefaultValue = [startOfDay(subDays(now, 2)), endOfDay(now)] as DatePair; this.filterFormInputs = { dateRange: { label: this.page.locator("label", { @@ -116,8 +104,7 @@ export class AdminReceiverStatusPage extends BasePage { name: "Change...", }), modalOverlay: dateRangeOverlay, - expectedModalOverlayText: - "Select date range to show. (Max 10 days span)FromToUpdate", + expectedModalOverlayText: "Select date range to show. (Max 10 days span)FromToUpdate", modalOverlayCalendar: dateRangeOverlay.getByRole("application"), modalPrimaryButton: dateRangeOverlay.getByRole("button", { name: "Update", @@ -144,22 +131,15 @@ export class AdminReceiverStatusPage extends BasePage { name: "Receiver Name:", }), expectedDefaultValue: "", - tooltip: this.page - .getByTestId("tooltipWrapper") - .nth(0) - .getByRole("tooltip"), + tooltip: this.page.getByTestId("tooltipWrapper").nth(0).getByRole("tooltip"), value: "", }, resultMessage: { label: this.page.locator("label", { hasText: "Results Message:", }), - expectedTooltipText: - "Filter rows on the Result Message details. This value is found in the details.", - tooltip: this.page - .getByTestId("tooltipWrapper") - .nth(1) - .getByRole("tooltip"), + expectedTooltipText: "Filter rows on the Result Message details. This value is found in the details.", + tooltip: this.page.getByTestId("tooltipWrapper").nth(1).getByRole("tooltip"), input: this.page.getByRole("textbox", { name: "Results Message:", }), @@ -171,10 +151,7 @@ export class AdminReceiverStatusPage extends BasePage { hasText: "Success Type:", }), expectedTooltipText: "Show only rows in one of these states.", - tooltip: this.page - .getByTestId("tooltipWrapper") - .nth(2) - .getByRole("tooltip"), + tooltip: this.page.getByTestId("tooltipWrapper").nth(2).getByRole("tooltip"), input: this.page.getByRole("combobox", { name: "Success Type:", }), @@ -192,10 +169,7 @@ export class AdminReceiverStatusPage extends BasePage { * Error expected additionally if user context isn't admin */ get isPageLoadExpected() { - return ( - super.isPageLoadExpected && - this.testArgs.storageState === this.testArgs.adminLogin.path - ); + return super.isPageLoadExpected && this.testArgs.storageState === this.testArgs.adminLogin.path; } get receiverStatus() { @@ -213,10 +187,7 @@ export class AdminReceiverStatusPage extends BasePage { const url = new URL(request.url()); const startDate = url.searchParams.get("start_date"); const endDate = url.searchParams.get("end_date"); - const range = - startDate && endDate - ? ([new Date(startDate), new Date(endDate)] as DatePair) - : undefined; + const range = startDate && endDate ? ([new Date(startDate), new Date(endDate)] as DatePair) : undefined; return { json: this.createMockReceiverStatuses(range), @@ -233,27 +204,18 @@ export class AdminReceiverStatusPage extends BasePage { const url = new URL(apiRes.url()); const startDate = url.searchParams.get("start_date"); const endDate = url.searchParams.get("end_date"); - const range = - startDate && endDate - ? ([new Date(startDate), new Date(endDate)] as DatePair) - : undefined; + const range = startDate && endDate ? ([new Date(startDate), new Date(endDate)] as DatePair) : undefined; this._receiverStatus = data; - this._timePeriodData = range - ? this.createTimePeriodData({ data, range }) - : []; + this._timePeriodData = range ? this.createTimePeriodData({ data, range }) : []; }, ]; } - createMockReceiverStatuses( - ...args: Parameters - ) { + createMockReceiverStatuses(...args: Parameters) { return createMockGetReceiverStatus(...args); } - createTimePeriodData( - ...args: Parameters - ) { + createTimePeriodData(...args: Parameters) { return createStatusTimePeriodData(...args); } @@ -281,11 +243,7 @@ export class AdminReceiverStatusPage extends BasePage { }); } - getExpectedReceiverStatusRowTitle( - organizationName: string, - receiverName: string, - successRate: number | string, - ) { + getExpectedReceiverStatusRowTitle(organizationName: string, receiverName: string, successRate: number | string) { return [organizationName, receiverName, successRate, "%"].join(""); } @@ -303,16 +261,14 @@ export class AdminReceiverStatusPage extends BasePage { allCustom: async () => { return (await days.all()).map((d) => Object.assign(d, { - timePeriods: - this.getReceiverStatusRowDisplayDayTimePeriods(d), + timePeriods: this.getReceiverStatusRowDisplayDayTimePeriods(d), }), ); }, nthCustom: (nth: number) => { const day = days.nth(nth); return Object.assign(day, { - timePeriods: - this.getReceiverStatusRowDisplayDayTimePeriods(day), + timePeriods: this.getReceiverStatusRowDisplayDayTimePeriods(day), }); }, }); @@ -334,39 +290,21 @@ export class AdminReceiverStatusPage extends BasePage { }: AdminReceiverStatusPageUpdateFiltersProps) { // API request will only fire if date ranges are different const isDateRangeDifferent = - dateRange == null || - this.getIsDateRangesDifferent( - this.filterFormInputs.dateRange.value, - dateRange.value, - ); - const isRequestAwaitedBool = - dateRange != null && - isDateRangeDifferent && - dateRange.isRequestAwaited !== false; + dateRange == null || this.getIsDateRangesDifferent(this.filterFormInputs.dateRange.value, dateRange.value); + const isRequestAwaitedBool = dateRange != null && isDateRangeDifferent && dateRange.isRequestAwaited !== false; const p = isRequestAwaitedBool - ? this.page.waitForRequest( - AdminReceiverStatusPage.API_RECEIVER_STATUS, - ) + ? this.page.waitForRequest(AdminReceiverStatusPage.API_RECEIVER_STATUS) : Promise.resolve(); if (dateRange && isDateRangeDifferent) { const { value, inputMethod } = dateRange; await this.updateFilterDateRange(...value, inputMethod); } - if ( - receiverName != null && - receiverName !== this.filterFormInputs.receiverName.value - ) + if (receiverName != null && receiverName !== this.filterFormInputs.receiverName.value) await this.updateFilterReceiverName(receiverName); - if ( - resultMessage != null && - resultMessage !== this.filterFormInputs.resultMessage.value - ) + if (resultMessage != null && resultMessage !== this.filterFormInputs.resultMessage.value) await this.updateFilterResultMessage(resultMessage); - if ( - successType != null && - successType !== this.filterFormInputs.successType.value - ) + if (successType != null && successType !== this.filterFormInputs.successType.value) await this.updateFilterSuccessType(successType); if (!isRequestAwaitedBool) return undefined as void; @@ -376,11 +314,7 @@ export class AdminReceiverStatusPage extends BasePage { return reqUrl; } - async updateFilterDateRange( - start: Date, - end: Date, - inputMethod: "textbox" | "calendar" = "textbox", - ) { + async updateFilterDateRange(start: Date, end: Date, inputMethod: "textbox" | "calendar" = "textbox") { const { button, modalStartInput, @@ -438,10 +372,8 @@ export class AdminReceiverStatusPage extends BasePage { dateRange: { value: this.filterFormInputs.dateRange.expectedDefaultValue, }, - receiverName: - this.filterFormInputs.receiverName.expectedDefaultValue, - resultMessage: - this.filterFormInputs.resultMessage.expectedDefaultValue, + receiverName: this.filterFormInputs.receiverName.expectedDefaultValue, + resultMessage: this.filterFormInputs.resultMessage.expectedDefaultValue, successType: this.filterFormInputs.successType.expectedDefaultValue, }; return await this.updateFilters(resetValues); @@ -471,9 +403,7 @@ export class AdminReceiverStatusPage extends BasePage { async testReceiverStatusDisplay() { const [startDate, endDate] = this.filterFormInputs.dateRange.value; const statusRows = this.receiverStatusRowsLocator; - await expect(statusRows).toHaveCount( - new Set(this.receiverStatus?.map((r) => r.receiverId)).size, - ); + await expect(statusRows).toHaveCount(new Set(this.receiverStatus?.map((r) => r.receiverId)).size); const expectedDaysText = [ dateShortFormat(startDate), @@ -482,13 +412,7 @@ export class AdminReceiverStatusPage extends BasePage { ].join(" "); for (const [ i, - { - days, - successRate, - organizationName, - receiverName, - successRateType, - }, + { days, successRate, organizationName, receiverName, successRateType }, ] of this.timePeriodData.entries()) { const { title, display, days: daysLoc } = statusRows.nthCustom(i); @@ -497,9 +421,7 @@ export class AdminReceiverStatusPage extends BasePage { receiverName, successRate, ); - const expectedClass = new RegExp( - SUCCESS_RATE_CLASSNAME_MAP[successRateType], - ); + const expectedClass = new RegExp(SUCCESS_RATE_CLASSNAME_MAP[successRateType]); await expect(title).toBeVisible(); await expect(title).toHaveText(expectedTitleText); @@ -516,9 +438,7 @@ export class AdminReceiverStatusPage extends BasePage { for (const [i, { successRateType }] of timePeriods.entries()) { const sliceEle = daySlices.nth(i); - const expectedClass = new RegExp( - SUCCESS_RATE_CLASSNAME_MAP[successRateType], - ); + const expectedClass = new RegExp(SUCCESS_RATE_CLASSNAME_MAP[successRateType]); await expect(sliceEle).toBeVisible(); await expect(sliceEle).toHaveClass(expectedClass); diff --git a/frontend-react/e2e/pages/daily-data-details.ts b/frontend-react/e2e/pages/authenticated/daily-data-details.ts similarity index 90% rename from frontend-react/e2e/pages/daily-data-details.ts rename to frontend-react/e2e/pages/authenticated/daily-data-details.ts index 06d382632b9..ed98347e902 100644 --- a/frontend-react/e2e/pages/daily-data-details.ts +++ b/frontend-react/e2e/pages/authenticated/daily-data-details.ts @@ -1,8 +1,8 @@ -import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "./BasePage"; import { API_WATERS_REPORT, URL_REPORT_DETAILS } from "./report-details"; -import { RSDelivery, RSFacility } from "../../src/config/endpoints/deliveries"; -import { MOCK_GET_DELIVERY } from "../mocks/delivery"; -import { MOCK_GET_FACILITIES } from "../mocks/facilities"; +import { RSDelivery, RSFacility } from "../../../src/config/endpoints/deliveries"; +import { MOCK_GET_DELIVERY } from "../../mocks/delivery"; +import { MOCK_GET_FACILITIES } from "../../mocks/facilities"; +import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "../BasePage"; const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; diff --git a/frontend-react/e2e/pages/daily-data.ts b/frontend-react/e2e/pages/authenticated/daily-data.ts similarity index 97% rename from frontend-react/e2e/pages/daily-data.ts rename to frontend-react/e2e/pages/authenticated/daily-data.ts index 61196131708..fa41af64f16 100644 --- a/frontend-react/e2e/pages/daily-data.ts +++ b/frontend-react/e2e/pages/authenticated/daily-data.ts @@ -1,16 +1,16 @@ import { expect, Page } from "@playwright/test"; import { format } from "date-fns"; -import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "./BasePage"; import { API_WATERS_ORG } from "./report-details"; -import { RSReceiver } from "../../src/config/endpoints/settings"; -import { TEST_ORG_UP_RECEIVER_FULL_ELR } from "../helpers/utils"; +import { RSReceiver } from "../../../src/config/endpoints/settings"; +import { TEST_ORG_UP_RECEIVER_FULL_ELR } from "../../helpers/utils"; import { MOCK_GET_DELIVERIES_IGNORE, MOCK_GET_DELIVERIES_IGNORE_FILENAME, MOCK_GET_DELIVERIES_IGNORE_FULL_ELR, MOCK_GET_DELIVERIES_IGNORE_REPORT_ID, -} from "../mocks/deliveries"; -import { MOCK_GET_RECEIVERS_AK, MOCK_GET_RECEIVERS_IGNORE } from "../mocks/organizations"; +} from "../../mocks/deliveries"; +import { MOCK_GET_RECEIVERS_AK, MOCK_GET_RECEIVERS_IGNORE } from "../../mocks/organizations"; +import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "../BasePage"; export class DailyDataPage extends BasePage { static readonly URL_DAILY_DATA = "/daily-data"; diff --git a/frontend-react/e2e/pages/last-mile-failures.ts b/frontend-react/e2e/pages/authenticated/last-mile-failures.ts similarity index 79% rename from frontend-react/e2e/pages/last-mile-failures.ts rename to frontend-react/e2e/pages/authenticated/last-mile-failures.ts index 86baae6ac4f..6b139675de2 100644 --- a/frontend-react/e2e/pages/last-mile-failures.ts +++ b/frontend-react/e2e/pages/authenticated/last-mile-failures.ts @@ -1,8 +1,5 @@ import { Page } from "@playwright/test"; -import { - MOCK_GET_RESEND, - MOCK_GET_SEND_FAILURES, -} from "../mocks/lastMilefailures"; +import { MOCK_GET_RESEND, MOCK_GET_SEND_FAILURES } from "../../mocks/lastMilefailures"; const URL_LAST_MILE = "/admin/lastmile"; const API_GET_RESEND = "/api/adm/getresend?days_to_show=15"; @@ -14,10 +11,7 @@ export async function goto(page: Page) { }); } -export async function mockGetSendFailuresResponse( - page: Page, - responseStatus = 200, -) { +export async function mockGetSendFailuresResponse(page: Page, responseStatus = 200) { await page.route(API_GET_SEND_FAILURES, async (route) => { const json = MOCK_GET_SEND_FAILURES; await route.fulfill({ json, status: responseStatus }); diff --git a/frontend-react/e2e/pages/message-details.ts b/frontend-react/e2e/pages/authenticated/message-details.ts similarity index 76% rename from frontend-react/e2e/pages/message-details.ts rename to frontend-react/e2e/pages/authenticated/message-details.ts index f989d00d1f7..ba57fadeba3 100644 --- a/frontend-react/e2e/pages/message-details.ts +++ b/frontend-react/e2e/pages/authenticated/message-details.ts @@ -1,6 +1,6 @@ import { Page } from "@playwright/test"; -import { MESSAGE_ID } from "../pages/message-id-search"; +import { MESSAGE_ID } from "../../pages/authenticated/message-id-search"; export const URL_MESSAGE_DETAILS = `/message-details/${MESSAGE_ID}`; diff --git a/frontend-react/e2e/pages/message-id-search.ts b/frontend-react/e2e/pages/authenticated/message-id-search.ts similarity index 100% rename from frontend-react/e2e/pages/message-id-search.ts rename to frontend-react/e2e/pages/authenticated/message-id-search.ts diff --git a/frontend-react/e2e/pages/organization.ts b/frontend-react/e2e/pages/authenticated/organization.ts similarity index 64% rename from frontend-react/e2e/pages/organization.ts rename to frontend-react/e2e/pages/authenticated/organization.ts index bbac970dd64..413e69fe734 100644 --- a/frontend-react/e2e/pages/organization.ts +++ b/frontend-react/e2e/pages/authenticated/organization.ts @@ -1,10 +1,6 @@ -import { - BasePage, - BasePageTestArgs, - type RouteHandlerFulfillEntry, -} from "./BasePage"; -import { RSOrganizationSettings } from "../../src/config/endpoints/settings"; -import { MOCK_GET_ORGANIZATION_SETTINGS_LIST } from "../mocks/organizations"; +import { RSOrganizationSettings } from "../../../src/config/endpoints/settings"; +import { MOCK_GET_ORGANIZATION_SETTINGS_LIST } from "../../mocks/organizations"; +import { BasePage, BasePageTestArgs, type RouteHandlerFulfillEntry } from "../BasePage"; export class OrganizationPage extends BasePage { static readonly API_ORGANIZATIONS = "/api/settings/organizations"; @@ -23,19 +19,13 @@ export class OrganizationPage extends BasePage { this._organizationSettings = []; this.addResponseHandlers([ - [ - OrganizationPage.API_ORGANIZATIONS, - async (res) => (this._organizationSettings = await res.json()), - ], + [OrganizationPage.API_ORGANIZATIONS, async (res) => (this._organizationSettings = await res.json())], ]); this.addMockRouteHandlers([this.createMockOrganizationHandler()]); } get isPageLoadExpected() { - return ( - super.isPageLoadExpected && - this.testArgs.storageState === this.testArgs.adminLogin.path - ); + return super.isPageLoadExpected && this.testArgs.storageState === this.testArgs.adminLogin.path; } createMockOrganizationHandler(): RouteHandlerFulfillEntry { diff --git a/frontend-react/e2e/pages/report-details.ts b/frontend-react/e2e/pages/authenticated/report-details.ts similarity index 95% rename from frontend-react/e2e/pages/report-details.ts rename to frontend-react/e2e/pages/authenticated/report-details.ts index 6b4a4abb422..99e1b8163ed 100644 --- a/frontend-react/e2e/pages/report-details.ts +++ b/frontend-react/e2e/pages/authenticated/report-details.ts @@ -8,11 +8,11 @@ import { MOCK_GET_DELIVERIES_IGNORE_FILENAME, MOCK_GET_DELIVERIES_IGNORE_FULL_ELR, MOCK_GET_DELIVERIES_IGNORE_REPORT_ID, -} from "../mocks/deliveries"; -import { MOCK_GET_DELIVERY } from "../mocks/delivery"; -import { MOCK_GET_FACILITIES } from "../mocks/facilities"; -import { MOCK_GET_HISTORY_REPORT } from "../mocks/historyReport"; -import { MOCK_GET_SUBMISSION_HISTORY } from "../mocks/submissionHistory"; +} from "../../mocks/deliveries"; +import { MOCK_GET_DELIVERY } from "../../mocks/delivery"; +import { MOCK_GET_FACILITIES } from "../../mocks/facilities"; +import { MOCK_GET_HISTORY_REPORT } from "../../mocks/historyReport"; +import { MOCK_GET_SUBMISSION_HISTORY } from "../../mocks/submissionHistory"; export const URL_REPORT_DETAILS = "/report-details"; export const API_WATERS_REPORT = "**/api/waters/report"; diff --git a/frontend-react/e2e/pages/submission-history.ts b/frontend-react/e2e/pages/authenticated/submission-history.ts similarity index 71% rename from frontend-react/e2e/pages/submission-history.ts rename to frontend-react/e2e/pages/authenticated/submission-history.ts index e65b4792397..f09dad1bf5a 100644 --- a/frontend-react/e2e/pages/submission-history.ts +++ b/frontend-react/e2e/pages/authenticated/submission-history.ts @@ -1,6 +1,6 @@ import { expect, Page } from "@playwright/test"; -import { MOCK_GET_SUBMISSION_HISTORY } from "../mocks/submissionHistory"; -import { MOCK_GET_SUBMISSIONS } from "../mocks/submissions"; +import { MOCK_GET_SUBMISSION_HISTORY } from "../../mocks/submissionHistory"; +import { MOCK_GET_SUBMISSIONS } from "../../mocks/submissions"; export const URL_SUBMISSION_HISTORY = "/submissions"; export const API_GET_REPORT_HISTORY = `**/api/waters/report/**`; @@ -21,11 +21,7 @@ export function getOrgSubmissionsAPI(org: string) { return `**/api/waters/org/${org}/submissions?*`; } -export async function mockGetSubmissionsResponse( - page: Page, - org: string, - responseStatus = 200, -) { +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; @@ -33,10 +29,7 @@ export async function mockGetSubmissionsResponse( }); } -export async function mockGetReportHistoryResponse( - page: Page, - responseStatus = 200, -) { +export async function mockGetReportHistoryResponse(page: Page, responseStatus = 200) { await page.route(API_GET_REPORT_HISTORY, async (route) => { const json = MOCK_GET_SUBMISSION_HISTORY; await route.fulfill({ json, status: responseStatus }); @@ -49,33 +42,21 @@ export async function openReportIdDetailPage(page: Page, id: string) { } export async function title(page: Page) { - await expect(page).toHaveTitle( - /ReportStream - CDC's free, interoperable data transfer platform/, - ); + 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", - ); + await expect(page.locator(".usa-table th").nth(1)).toHaveText("Date/time submitted"); await expect(page.locator(".usa-table th").nth(2)).toHaveText(/File/); await expect(page.locator(".usa-table th").nth(3)).toHaveText(/Records/); await expect(page.locator(".usa-table th").nth(4)).toHaveText(/Status/); } -export async function breadcrumbLink( - page: Page, - index: number, - linkName: string, - expectedUrl: string, -) { +export async function breadcrumbLink(page: Page, index: number, linkName: string, expectedUrl: string) { const breadcrumbLinks = page.locator(".usa-breadcrumb ol li"); await expect(breadcrumbLinks.nth(index)).toHaveText(linkName); - await breadcrumbLinks - .nth(index) - .getByRole("link", { name: linkName }) - .click(); + await breadcrumbLinks.nth(index).getByRole("link", { name: linkName }).click(); await expect(page.locator("h1")).toBeAttached(); await expect(page).toHaveURL(expectedUrl); } diff --git a/frontend-react/e2e/pages/about-side-navigation.ts b/frontend-react/e2e/pages/public/about-side-navigation.ts similarity index 100% rename from frontend-react/e2e/pages/about-side-navigation.ts rename to frontend-react/e2e/pages/public/about-side-navigation.ts diff --git a/frontend-react/e2e/pages/about.ts b/frontend-react/e2e/pages/public/about/about.ts similarity index 85% rename from frontend-react/e2e/pages/about.ts rename to frontend-react/e2e/pages/public/about/about.ts index 2189c703f39..c1c0d3b6082 100644 --- a/frontend-react/e2e/pages/about.ts +++ b/frontend-react/e2e/pages/public/about/about.ts @@ -1,4 +1,4 @@ -import { BasePage, BasePageTestArgs } from "./BasePage"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; export class AboutPage extends BasePage { constructor(testArgs: BasePageTestArgs) { diff --git a/frontend-react/e2e/pages/our-network.ts b/frontend-react/e2e/pages/public/about/our-network.ts similarity index 100% rename from frontend-react/e2e/pages/our-network.ts rename to frontend-react/e2e/pages/public/about/our-network.ts diff --git a/frontend-react/e2e/pages/roadmap.ts b/frontend-react/e2e/pages/public/about/roadmap.ts similarity index 100% rename from frontend-react/e2e/pages/roadmap.ts rename to frontend-react/e2e/pages/public/about/roadmap.ts diff --git a/frontend-react/e2e/pages/security.ts b/frontend-react/e2e/pages/public/about/security.ts similarity index 91% rename from frontend-react/e2e/pages/security.ts rename to frontend-react/e2e/pages/public/about/security.ts index 8294a43283e..5d494e97795 100644 --- a/frontend-react/e2e/pages/security.ts +++ b/frontend-react/e2e/pages/public/about/security.ts @@ -1,5 +1,5 @@ import { expect, Page } from "@playwright/test"; -import { BasePage, BasePageTestArgs } from "./BasePage"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; export class SecurityPage extends BasePage { constructor(testArgs: BasePageTestArgs) { diff --git a/frontend-react/e2e/pages/getting-started/receiving-data.ts b/frontend-react/e2e/pages/public/getting-started/receiving-data.ts similarity index 88% rename from frontend-react/e2e/pages/getting-started/receiving-data.ts rename to frontend-react/e2e/pages/public/getting-started/receiving-data.ts index d87fb8acdb7..3ccd227e24f 100644 --- a/frontend-react/e2e/pages/getting-started/receiving-data.ts +++ b/frontend-react/e2e/pages/public/getting-started/receiving-data.ts @@ -1,4 +1,4 @@ -import { BasePage, BasePageTestArgs } from "../BasePage"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; export class ReceivingDataPage extends BasePage { constructor(testArgs: BasePageTestArgs) { diff --git a/frontend-react/e2e/pages/getting-started/sending-data.ts b/frontend-react/e2e/pages/public/getting-started/sending-data.ts similarity index 88% rename from frontend-react/e2e/pages/getting-started/sending-data.ts rename to frontend-react/e2e/pages/public/getting-started/sending-data.ts index 9bb57acf9a5..47aa28823d5 100644 --- a/frontend-react/e2e/pages/getting-started/sending-data.ts +++ b/frontend-react/e2e/pages/public/getting-started/sending-data.ts @@ -1,4 +1,4 @@ -import { BasePage, BasePageTestArgs } from "../BasePage"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; export class SendingDataPage extends BasePage { constructor(testArgs: BasePageTestArgs) { diff --git a/frontend-react/e2e/pages/header.ts b/frontend-react/e2e/pages/public/header.ts similarity index 63% rename from frontend-react/e2e/pages/header.ts rename to frontend-react/e2e/pages/public/header.ts index b4929379008..1ed78a50c6e 100644 --- a/frontend-react/e2e/pages/header.ts +++ b/frontend-react/e2e/pages/public/header.ts @@ -6,11 +6,7 @@ export async function clickOnHome(page: Page) { } export async function clickOnAbout(page: Page) { - await page - .getByTestId("header") - .getByTestId("navDropDownButton") - .getByText("About") - .click(); + await page.getByTestId("header").getByTestId("navDropDownButton").getByText("About").click(); expect(page.getByText("About ReportStream")).toBeTruthy(); expect(page.getByText("Our network")).toBeTruthy(); @@ -21,34 +17,22 @@ export async function clickOnAbout(page: Page) { } export async function clickOnGettingStarted(page: Page) { - await page - .getByTestId("header") - .getByRole("link", { name: "Getting started" }) - .click(); + await page.getByTestId("header").getByRole("link", { name: "Getting started" }).click(); await expect(page).toHaveURL(/getting-started/); } export async function clickOnDevelopers(page: Page) { - await page - .getByTestId("header") - .getByRole("link", { name: "Developers" }) - .click(); + await page.getByTestId("header").getByRole("link", { name: "Developers" }).click(); await expect(page).toHaveURL(/.*developer-resources/); } export async function clickOnYourConnection(page: Page) { - await page - .getByTestId("header") - .getByRole("link", { name: "Your Connection" }) - .click(); + await page.getByTestId("header").getByRole("link", { name: "Your Connection" }).click(); await expect(page).toHaveURL(/.*managing-your-connection/); } export async function clickOnSupport(page: Page) { - await page - .getByTestId("header") - .getByRole("link", { name: "Support" }) - .click(); + await page.getByTestId("header").getByRole("link", { name: "Support" }).click(); await expect(page).toHaveURL(/.*support/); } diff --git a/frontend-react/e2e/pages/homepage.ts b/frontend-react/e2e/pages/public/homepage.ts similarity index 100% rename from frontend-react/e2e/pages/homepage.ts rename to frontend-react/e2e/pages/public/homepage.ts diff --git a/frontend-react/e2e/pages/managing-your-connection.ts b/frontend-react/e2e/pages/public/managing-your-connection/managing-your-connection.ts similarity index 91% rename from frontend-react/e2e/pages/managing-your-connection.ts rename to frontend-react/e2e/pages/public/managing-your-connection/managing-your-connection.ts index 6098bec9e63..31427cb506b 100644 --- a/frontend-react/e2e/pages/managing-your-connection.ts +++ b/frontend-react/e2e/pages/public/managing-your-connection/managing-your-connection.ts @@ -1,5 +1,5 @@ import { expect, Page } from "@playwright/test"; -import { BasePage, BasePageTestArgs } from "./BasePage"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; export async function onLoad(page: Page) { await expect(page).toHaveURL(/managing-your-connection/); diff --git a/frontend-react/e2e/pages/refer-healthcare.ts b/frontend-react/e2e/pages/public/managing-your-connection/refer-healthcare.ts similarity index 88% rename from frontend-react/e2e/pages/refer-healthcare.ts rename to frontend-react/e2e/pages/public/managing-your-connection/refer-healthcare.ts index b86152b914f..a5805d5a9c0 100644 --- a/frontend-react/e2e/pages/refer-healthcare.ts +++ b/frontend-react/e2e/pages/public/managing-your-connection/refer-healthcare.ts @@ -1,4 +1,4 @@ -import { BasePage, BasePageTestArgs } from "./BasePage"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; export class ReferHealthcarePage extends BasePage { constructor(testArgs: BasePageTestArgs) { diff --git a/frontend-react/e2e/pages/resources.ts b/frontend-react/e2e/pages/public/resources.ts similarity index 100% rename from frontend-react/e2e/pages/resources.ts rename to frontend-react/e2e/pages/public/resources.ts diff --git a/frontend-react/e2e/pages/support.ts b/frontend-react/e2e/pages/public/support.ts similarity index 87% rename from frontend-react/e2e/pages/support.ts rename to frontend-react/e2e/pages/public/support.ts index ae5bc223708..119815da6b2 100644 --- a/frontend-react/e2e/pages/support.ts +++ b/frontend-react/e2e/pages/public/support.ts @@ -1,4 +1,4 @@ -import { BasePage, BasePageTestArgs } from "./BasePage"; +import { BasePage, BasePageTestArgs } from "../BasePage"; export class SupportPage extends BasePage { constructor(testArgs: BasePageTestArgs) { diff --git a/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts index 33fcf977608..cbe14099d98 100644 --- a/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts @@ -1,10 +1,10 @@ import { addDays, endOfDay, startOfDay, subDays } from "date-fns"; -import type { RSOrganizationSettings } from "../../../../src/config/endpoints/settings"; -import { SuccessRate } from "../../../../src/pages/admin/receiver-dashboard/utils"; -import { durationFormatShort } from "../../../../src/utils/DateTimeUtils"; -import { formatDate } from "../../../../src/utils/misc"; -import { AdminReceiverStatusPage } from "../../../pages/admin/receiver-status"; -import { test as baseTest, expect, logins } from "../../../test"; +import type { RSOrganizationSettings } from "../../../../../src/config/endpoints/settings"; +import { SuccessRate } from "../../../../../src/pages/admin/receiver-dashboard/utils"; +import { durationFormatShort } from "../../../../../src/utils/DateTimeUtils"; +import { formatDate } from "../../../../../src/utils/misc"; +import { AdminReceiverStatusPage } from "../../../../pages/authenticated/admin/receiver-status"; +import { test as baseTest, expect, logins } from "../../../../test"; export interface AdminReceiverStatusPageFixtures { adminReceiverStatusPage: AdminReceiverStatusPage; diff --git a/frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts index f4da6d4a3f1..bf2dc36b129 100644 --- a/frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/daily-data-details-page.spec.ts @@ -1,8 +1,8 @@ import { expect } from "@playwright/test"; import { tableDataCellValue } from "../../../helpers/utils"; -import { detailsTableHeaders } from "../../../pages/daily-data"; -import { DailyDataDetailsPage } from "../../../pages/daily-data-details"; -import * as reportDetails from "../../../pages/report-details"; +import { detailsTableHeaders } from "../../../pages/authenticated/daily-data"; +import { DailyDataDetailsPage } from "../../../pages/authenticated/daily-data-details"; +import * as reportDetails from "../../../pages/authenticated/report-details"; import { test as baseTest } from "../../../test"; export interface DailyDataDetailsPageFixtures { diff --git a/frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts index 4397cbe4037..f172686be3e 100644 --- a/frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/daily-data-page.spec.ts @@ -9,7 +9,7 @@ import { TEST_ORG_AK_RECEIVER, TEST_ORG_UP_RECEIVER_FULL_ELR, } from "../../../helpers/utils"; -import * as dailyData from "../../../pages/daily-data"; +import * as dailyData from "../../../pages/authenticated/daily-data"; import { applyButton, DailyDataPage, @@ -30,11 +30,11 @@ import { startTime, startTimeClear, tableHeaders, -} from "../../../pages/daily-data"; +} from "../../../pages/authenticated/daily-data"; import { mockGetDeliveriesForOrgAlaskaResponse, mockGetDeliveriesForOrgIgnoreResponse, -} from "../../../pages/report-details"; +} from "../../../pages/authenticated/report-details"; import { test as baseTest } from "../../../test"; const defaultStartTime = "9:00am"; diff --git a/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts index 78d88094f9b..1c24ecf10d8 100644 --- a/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import { tableRows } from "../../../helpers/utils"; -import * as lastMileFailures from "../../../pages/last-mile-failures"; +import * as lastMileFailures from "../../../pages/authenticated/last-mile-failures"; test.describe("Last Mile Failure page", () => { test.describe("not authenticated", () => { diff --git a/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts index f0e902351b5..7378982632d 100644 --- a/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts @@ -3,11 +3,11 @@ import fs from "node:fs"; import { parseFileLocation } from "../../../../src/utils/misc"; import { tableRows } from "../../../helpers/utils"; import { MOCK_GET_MESSAGE } from "../../../mocks/messages"; -import * as messageDetails from "../../../pages/message-details"; -import { URL_MESSAGE_DETAILS } from "../../../pages/message-details"; -import * as messageIdSearch from "../../../pages/message-id-search"; -import { MESSAGE_ID } from "../../../pages/message-id-search"; -import { mockGetHistoryReportResponse } from "../../../pages/report-details"; +import * as messageDetails from "../../../pages/authenticated/message-details"; +import { URL_MESSAGE_DETAILS } from "../../../pages/authenticated/message-details"; +import * as messageIdSearch from "../../../pages/authenticated/message-id-search"; +import { MESSAGE_ID } from "../../../pages/authenticated/message-id-search"; +import { mockGetHistoryReportResponse } from "../../../pages/authenticated/report-details"; test.describe("Message Details Page", () => { test.describe("not authenticated", () => { test("redirects to login", async ({ page }) => { diff --git a/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts index 9564d028907..5906ff8929e 100644 --- a/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts @@ -1,10 +1,10 @@ import { expect, test } from "@playwright/test"; import { noData, tableRows } from "../../../helpers/utils"; import { MOCK_GET_MESSAGE, MOCK_GET_MESSAGES } from "../../../mocks/messages"; -import * as messageIdSearch from "../../../pages/message-id-search"; -import { MESSAGE_ID, URL_MESSAGE_ID_SEARCH } from "../../../pages/message-id-search"; -import { openReportIdDetailPage } from "../../../pages/submission-history"; -import * as submissionHistory from "../../../pages/submission-history"; +import * as messageIdSearch from "../../../pages/authenticated/message-id-search"; +import { MESSAGE_ID, URL_MESSAGE_ID_SEARCH } from "../../../pages/authenticated/message-id-search"; +import { openReportIdDetailPage } from "../../../pages/authenticated/submission-history"; +import * as submissionHistory from "../../../pages/authenticated/submission-history"; test.describe("Message ID Search Page", () => { test.describe("not authenticated", () => { diff --git a/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts index db0e119d15a..d2aecc8499c 100644 --- a/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts @@ -3,7 +3,7 @@ import { readFileSync } from "node:fs"; import { join } from "node:path"; import { fileURLToPath } from "node:url"; import { MOCK_GET_ORGANIZATION_SETTINGS_LIST } from "../../../mocks/organizations"; -import { OrganizationPage } from "../../../pages/organization"; +import { OrganizationPage } from "../../../pages/authenticated/organization"; import { test as baseTest } from "../../../test"; const __dirname = fileURLToPath(import.meta.url); @@ -159,7 +159,7 @@ test.describe("Admin Organization Settings Page", () => { await saveButton.click(); const download = await downloadProm; - const expectedFile = readFileSync(join(__dirname, "../../../mocks/prime-orgs.csv"), { + const expectedFile = readFileSync(join(__dirname, "../../../../mocks/prime-orgs.csv"), { encoding: "utf-8", }); const stream = await download.createReadStream(); diff --git a/frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts index d1061c964d2..98f6a4f684c 100644 --- a/frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/submission-history-page.spec.ts @@ -1,8 +1,8 @@ import { expect, test } from "@playwright/test"; import { noData, selectTestOrg, tableDataCellValue, tableRows, TEST_ORG_IGNORE } from "../../../helpers/utils"; -import * as submissionHistory from "../../../pages/submission-history"; -import { openReportIdDetailPage } from "../../../pages/submission-history"; +import * as submissionHistory from "../../../pages/authenticated/submission-history"; +import { openReportIdDetailPage } from "../../../pages/authenticated/submission-history"; const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; test.describe("Submission history page", () => { diff --git a/frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts index 59d84e9c22a..a25780ae0b8 100644 --- a/frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/submissions-details-page.spec.ts @@ -1,8 +1,8 @@ import { expect, test } from "@playwright/test"; import { selectTestOrg } from "../../../helpers/utils"; -import * as reportDetails from "../../../pages/report-details"; -import * as submissionDetails from "../../../pages/submission-history"; -import { URL_SUBMISSION_HISTORY } from "../../../pages/submission-history"; +import * as reportDetails from "../../../pages/authenticated/report-details"; +import * as submissionDetails from "../../../pages/authenticated/submission-history"; +import { URL_SUBMISSION_HISTORY } from "../../../pages/authenticated/submission-history"; const id = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; test.describe("Submissions Details page", () => { diff --git a/frontend-react/e2e/spec/all/idletimeout.spec.ts b/frontend-react/e2e/spec/all/idletimeout.spec.ts index 3d2ae35eb96..0b35f0fd34d 100644 --- a/frontend-react/e2e/spec/all/idletimeout.spec.ts +++ b/frontend-react/e2e/spec/all/idletimeout.spec.ts @@ -1,7 +1,7 @@ import { expect } from "@playwright/test"; import process from "node:process"; -import { OrganizationPage } from "../../pages/organization"; +import { OrganizationPage } from "../../pages/authenticated/organization"; import { test as baseTest } from "../../test"; const timeout = parseInt(process.env.VITE_IDLE_TIMEOUT ?? "20000"); @@ -35,7 +35,7 @@ const test = baseTest.extend({ receiverLogin, storageState, frontendWarningsLogPath, - isFrontendWarningsLog + isFrontendWarningsLog, }); await page.goto(); await use(page); @@ -45,19 +45,14 @@ const test = baseTest.extend({ test.use({ storageState: "e2e/.auth/admin.json" }); test.skip("Does not trigger early", async ({ organizationPage }) => { - await expect( - organizationPage.page.getByRole("banner").first(), - ).toBeVisible(); + await expect(organizationPage.page.getByRole("banner").first()).toBeVisible(); await organizationPage.page.keyboard.down("Tab"); const start = new Date(); - await organizationPage.page.waitForRequest( - /\/oauth2\/default\/v1\/revoke/, - { - timeout: timeoutHigh, - }, - ); + await organizationPage.page.waitForRequest(/\/oauth2\/default\/v1\/revoke/, { + timeout: timeoutHigh, + }); const end = new Date(); diff --git a/frontend-react/e2e/spec/all/public/about/about-page.spec.ts b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts index 9f965a0c34d..88b7ea6894f 100644 --- a/frontend-react/e2e/spec/all/public/about/about-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts @@ -1,5 +1,5 @@ import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; -import { AboutPage } from "../../../../pages/about"; +import { AboutPage } from "../../../../pages/public/about/about"; import { test as baseTest, expect } from "../../../../test"; const URL_ABOUT = "/about"; diff --git a/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts b/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts index c07b65c88b1..b75cb06c1ad 100644 --- a/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; -import * as sideNav from "../../../../pages/about-side-navigation"; -import * as ourNetwork from "../../../../pages/our-network"; +import * as ourNetwork from "../../../../pages/public/about/our-network"; +import * as sideNav from "../../../../pages/public/about-side-navigation"; test.describe( "Our network page", { diff --git a/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts b/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts index 987ddb5eaa7..331e1d242c2 100644 --- a/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts @@ -1,9 +1,9 @@ import { expect, test } from "@playwright/test"; import * as internalLinks from "../../../../helpers/internal-links"; -import * as sideNav from "../../../../pages/about-side-navigation"; -import * as roadmap from "../../../../pages/roadmap"; -import { URL_ROADMAP } from "../../../../pages/roadmap"; +import * as roadmap from "../../../../pages/public/about/roadmap"; +import { URL_ROADMAP } from "../../../../pages/public/about/roadmap"; +import * as sideNav from "../../../../pages/public/about-side-navigation"; test.describe( "Product roadmap page", diff --git a/frontend-react/e2e/spec/all/public/about/security.spec.ts b/frontend-react/e2e/spec/all/public/about/security.spec.ts index b1bbe565e72..021ae975894 100644 --- a/frontend-react/e2e/spec/all/public/about/security.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/security.spec.ts @@ -1,5 +1,5 @@ import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; -import { SecurityPage } from "../../../../pages/security"; +import { SecurityPage } from "../../../../pages/public/about/security"; import { test as baseTest, expect } from "../../../../test"; const URL_SECURITY = "/about/security"; diff --git a/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts index ef177c7c4e9..281b916ad6a 100644 --- a/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts @@ -1,6 +1,6 @@ import site from "../../../../../src/content/site.json" assert { type: "json" }; import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; -import { ReceivingDataPage } from "../../../../pages/getting-started/receiving-data"; +import { ReceivingDataPage } from "../../../../pages/public/getting-started/receiving-data"; import { test as baseTest, expect } from "../../../../test"; export interface ReceivingDataPageFixtures { diff --git a/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts index 6fc94409aaf..90569f5043f 100644 --- a/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts @@ -1,6 +1,6 @@ import site from "../../../../../src/content/site.json" assert { type: "json" }; import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; -import { SendingDataPage } from "../../../../pages/getting-started/sending-data.js"; +import { SendingDataPage } from "../../../../pages/public/getting-started/sending-data.js"; import { test as baseTest, expect } from "../../../../test"; export interface SendingDataPageFixtures { diff --git a/frontend-react/e2e/spec/all/public/homepage.spec.ts b/frontend-react/e2e/spec/all/public/homepage.spec.ts index a13159b12f3..3104dd80a34 100644 --- a/frontend-react/e2e/spec/all/public/homepage.spec.ts +++ b/frontend-react/e2e/spec/all/public/homepage.spec.ts @@ -1,11 +1,11 @@ import { expect, test } from "@playwright/test"; import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; -import * as header from "../../../pages/header"; -import * as homepage from "../../../pages/homepage"; -import * as managingYourConnection from "../../../pages/managing-your-connection"; -import * as ourNetwork from "../../../pages/our-network"; -import * as security from "../../../pages/security"; +import * as ourNetwork from "../../../pages/public/about/our-network"; +import * as security from "../../../pages/public/about/security"; +import * as header from "../../../pages/public/header"; +import * as homepage from "../../../pages/public/homepage"; +import * as managingYourConnection from "../../../pages/public/managing-your-connection/managing-your-connection"; test.describe( "Homepage", diff --git a/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts index cb3c02e23f4..aeabc842587 100644 --- a/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts @@ -1,5 +1,5 @@ import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; -import { ManagingYourConnectionPage } from "../../../../pages/managing-your-connection"; +import { ManagingYourConnectionPage } from "../../../../pages/public/managing-your-connection/managing-your-connection"; import { test as baseTest, expect } from "../../../../test"; const cards = [ diff --git a/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts index ecf307eea36..5cc4a6a166c 100644 --- a/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts @@ -1,5 +1,5 @@ import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; -import { ReferHealthcarePage } from "../../../../pages/refer-healthcare"; +import { ReferHealthcarePage } from "../../../../pages/public/managing-your-connection/refer-healthcare"; import { test as baseTest, expect } from "../../../../test"; export interface ReferHealthcarePageFixtures { diff --git a/frontend-react/e2e/spec/all/public/resources-page.spec.ts b/frontend-react/e2e/spec/all/public/resources-page.spec.ts index cc69063dbf8..ed38f956418 100644 --- a/frontend-react/e2e/spec/all/public/resources-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/resources-page.spec.ts @@ -1,5 +1,5 @@ import { expect, test } from "@playwright/test"; -import * as resources from "../../../pages/resources"; +import * as resources from "../../../pages/public/resources"; // eslint-disable-next-line playwright/no-skipped-test test.describe.skip("Developer Resources page", () => { diff --git a/frontend-react/e2e/spec/all/public/support-page.spec.ts b/frontend-react/e2e/spec/all/public/support-page.spec.ts index 50beb809c8c..e501f97ef04 100644 --- a/frontend-react/e2e/spec/all/public/support-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/support-page.spec.ts @@ -1,6 +1,6 @@ import site from "../../../../src/content/site.json" assert { type: "json" }; import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; -import { SupportPage } from "../../../pages/support.js"; +import { SupportPage } from "../../../pages/public/support.js"; import { test as baseTest, expect } from "../../../test"; const cards = [ From 978dc6310df9cee0979744c29b0a874d95d889f9 Mon Sep 17 00:00:00 2001 From: etanb Date: Wed, 14 Aug 2024 17:01:47 -0400 Subject: [PATCH 03/17] begin creating a suite of helper functions --- frontend-react/e2e/helpers/utils.ts | 75 +++++++++++-------- .../e2e/spec/all/public/support-page.spec.ts | 15 +--- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/frontend-react/e2e/helpers/utils.ts b/frontend-react/e2e/helpers/utils.ts index 176c5aac7aa..88a4548d1ac 100644 --- a/frontend-react/e2e/helpers/utils.ts +++ b/frontend-react/e2e/helpers/utils.ts @@ -1,75 +1,78 @@ -import { expect, Page } from "@playwright/test"; import fs from "node:fs"; +import { BasePage } from "../pages/BasePage"; +import { expect } from "../test"; export const TEST_ORG_IGNORE = "ignore"; export const TEST_ORG_UP_RECEIVER_FULL_ELR = "FULL_ELR"; export const TEST_ORG_AK_RECEIVER = "elr"; -export async function scrollToFooter(page: Page) { +export async function scrollToFooter(basePage: BasePage) { // Scrolling to the bottom of the page - await page.locator("footer").scrollIntoViewIfNeeded(); + await basePage.page.locator("footer").scrollIntoViewIfNeeded(); } -export async function scrollToTop(page: Page) { +export async function scrollToTop(basePage: BasePage) { // Scroll to the top of the page - await page.evaluate(() => window.scrollTo(0, 0)); + await basePage.page.evaluate(() => window.scrollTo(0, 0)); } -export async function waitForAPIResponse(page: Page, requestUrl: string) { - const response = await page.waitForResponse((response) => response.url().includes(requestUrl)); +export async function waitForAPIResponse(basePage: BasePage, requestUrl: string) { + const response = await basePage.page.waitForResponse((response) => response.url().includes(requestUrl)); return response.status(); } -export function noData(page: Page) { - return page.getByText(/No available data/); +export function noData(basePage: BasePage) { + return basePage.page.getByText(/No available data/); } -export function tableRows(page: Page) { - return page.locator(".usa-table tbody").locator("tr"); +export function tableRows(basePage: BasePage) { + return basePage.page.locator(".usa-table tbody").locator("tr"); } -export async function fulfillGoogleAnalytics(page: Page) { +export async function fulfillGoogleAnalytics(basePage: BasePage) { // fulfill GA request so that we don't log it and alter the metrics - await page.route("https://www.google-analytics.com/**", (route) => route.fulfill({ status: 204, body: "" })); + await basePage.page.route("https://www.google-analytics.com/**", (route) => + route.fulfill({ status: 204, body: "" }), + ); } -export async function selectTestOrg(page: Page) { - await page.goto("/admin/settings", { +export async function selectTestOrg(basePage: BasePage) { + await basePage.page.goto("/admin/settings", { waitUntil: "domcontentloaded", }); - await waitForAPIResponse(page, "/api/settings/organizations"); + await waitForAPIResponse(basePage.page, "/api/settings/organizations"); - await page.getByTestId("gridContainer").waitFor({ state: "visible" }); - await page.getByTestId("textInput").fill(TEST_ORG_IGNORE); - await page.getByTestId("ignore_set").click(); + await basePage.page.getByTestId("gridContainer").waitFor({ state: "visible" }); + await basePage.page.getByTestId("textInput").fill(TEST_ORG_IGNORE); + await basePage.page.getByTestId("ignore_set").click(); } /** * Save session storage to file. Session storage is not handled in * playwright's storagestate. */ -export async function saveSessionStorage(userType: string, page: Page) { - const sessionJson = await page.evaluate(() => JSON.stringify(sessionStorage)); +export async function saveSessionStorage(userType: string, basePage: BasePage) { + const sessionJson = await basePage.page.evaluate(() => JSON.stringify(sessionStorage)); fs.writeFileSync(`e2e/.auth/${userType}-session.json`, sessionJson, "utf-8"); } -export async function restoreSessionStorage(userType: string, page: Page) { +export async function restoreSessionStorage(userType: string, basePage: BasePage) { const session = JSON.parse(fs.readFileSync(`e2e/.auth/${userType}-session.json`, "utf-8")); - await page.context().addInitScript((session) => { + await basePage.page.context().addInitScript((session) => { for (const [key, value] of Object.entries(session)) window.sessionStorage.setItem(key, value); }, session); } -export function tableDataCellValue(page: Page, row: number, column: number) { - return tableRows(page).nth(row).locator("td").nth(column).innerText(); +export function tableDataCellValue(basePage: BasePage, row: number, column: number) { + return tableRows(basePage.page).nth(row).locator("td").nth(column).innerText(); } /** * This method loops through all the cells in a column to compare with expected value. */ -export async function expectTableColumnValues(page: Page, columnNumber: number, expectedValue: string) { - const rowCount = await tableRows(page).count(); +export async function expectTableColumnValues(basePage: BasePage, columnNumber: number, expectedValue: string) { + const rowCount = await tableRows(basePage.page).count(); for (let i = 0; i < rowCount; i++) { - const columnValue = await tableRows(page).nth(i).locator("td").nth(columnNumber).innerText(); + const columnValue = await tableRows(basePage.page).nth(i).locator("td").nth(columnNumber).innerText(); expect(columnValue).toContain(expectedValue); } } @@ -78,7 +81,7 @@ export async function expectTableColumnValues(page: Page, columnNumber: number, * This method loops through all the cells in a date/time column to compare with a date value. */ export async function tableColumnDateTimeInRange( - page: Page, + basePage: BasePage, columnNumber: number, fromDate: string, toDate: string, @@ -86,12 +89,12 @@ export async function tableColumnDateTimeInRange( endTime: string, ) { let datesInRange = true; - const rowCount = await tableRows(page).count(); + const rowCount = await tableRows(basePage.page).count(); for (let i = 0; i < rowCount; i++) { const startDateTime = fromDateWithTime(fromDate, startTime); const endDateTime = toDateWithTime(toDate, endTime); - const columnValue = await tableRows(page).nth(i).locator("td").nth(columnNumber).innerText(); + const columnValue = await tableRows(basePage.page).nth(i).locator("td").nth(columnNumber).innerText(); const columnDate = new Date(columnValue); @@ -136,3 +139,13 @@ export function toDateWithTime(date: string, time: string) { } return toDateTime; } + +export async function testFooter(basePage: BasePage) { + await expect(basePage.page.footer).toBeAttached(); + await expect(basePage.page.footer).not.toBeInViewport(); + await scrollToFooter(basePage.page); + await expect(basePage.page.footer).toBeInViewport(); + await expect(basePage.page.getByTestId("govBanner")).not.toBeInViewport(); + await scrollToTop(basePage.page); + await expect(basePage.page.getByTestId("govBanner")).toBeInViewport(); +} diff --git a/frontend-react/e2e/spec/all/public/support-page.spec.ts b/frontend-react/e2e/spec/all/public/support-page.spec.ts index e501f97ef04..4f1d96d9211 100644 --- a/frontend-react/e2e/spec/all/public/support-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/support-page.spec.ts @@ -1,5 +1,5 @@ import site from "../../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; +import { scrollToFooter, scrollToTop, testFooter } from "../../../helpers/utils"; import { SupportPage } from "../../../pages/public/support.js"; import { test as baseTest, expect } from "../../../test"; @@ -81,17 +81,8 @@ test.describe("Support page", () => { } test.describe("Footer", () => { - test("has footer", async ({ supportPage }) => { - await expect(supportPage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ supportPage }) => { - await expect(supportPage.footer).not.toBeInViewport(); - await scrollToFooter(supportPage.page); - await expect(supportPage.footer).toBeInViewport(); - await expect(supportPage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(supportPage.page); - await expect(supportPage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ supportPage }) => { + await testFooter(supportPage); }); }); }); From 61317181ed6509c61bb45a2bd59d565bf8aeb162 Mon Sep 17 00:00:00 2001 From: etanb Date: Thu, 15 Aug 2024 14:45:00 -0400 Subject: [PATCH 04/17] add testFooter to basepage --- frontend-react/.eslintrc.cjs | 6 ++ frontend-react/e2e/helpers/utils.ts | 75 ++++++++---------- frontend-react/e2e/pages/BasePage.ts | 78 +++++++------------ .../spec/all/public/about/about-page.spec.ts | 14 +--- .../spec/all/public/about/security.spec.ts | 14 +--- .../getting-started/receiving-data.spec.ts | 14 +--- .../getting-started/sending-data.spec.ts | 14 +--- .../managing-your-connection-page.spec.ts | 16 +--- .../refer-healthcare-page.spec.ts | 14 +--- .../e2e/spec/all/public/support-page.spec.ts | 3 +- 10 files changed, 78 insertions(+), 170 deletions(-) diff --git a/frontend-react/.eslintrc.cjs b/frontend-react/.eslintrc.cjs index 4a4debd4a41..bc45efe1bfc 100644 --- a/frontend-react/.eslintrc.cjs +++ b/frontend-react/.eslintrc.cjs @@ -82,6 +82,12 @@ module.exports = { // TODO: investigate these for reconsideration or per-module ignoring "playwright/no-conditional-in-test": ["off"], "playwright/no-force-option": ["off"], + "playwright/expect-expect": [ + "error", + { + additionalAssertFunctionNames: ["testFooter"], + }, + ], }, }, ], diff --git a/frontend-react/e2e/helpers/utils.ts b/frontend-react/e2e/helpers/utils.ts index 88a4548d1ac..176c5aac7aa 100644 --- a/frontend-react/e2e/helpers/utils.ts +++ b/frontend-react/e2e/helpers/utils.ts @@ -1,78 +1,75 @@ +import { expect, Page } from "@playwright/test"; import fs from "node:fs"; -import { BasePage } from "../pages/BasePage"; -import { expect } from "../test"; export const TEST_ORG_IGNORE = "ignore"; export const TEST_ORG_UP_RECEIVER_FULL_ELR = "FULL_ELR"; export const TEST_ORG_AK_RECEIVER = "elr"; -export async function scrollToFooter(basePage: BasePage) { +export async function scrollToFooter(page: Page) { // Scrolling to the bottom of the page - await basePage.page.locator("footer").scrollIntoViewIfNeeded(); + await page.locator("footer").scrollIntoViewIfNeeded(); } -export async function scrollToTop(basePage: BasePage) { +export async function scrollToTop(page: Page) { // Scroll to the top of the page - await basePage.page.evaluate(() => window.scrollTo(0, 0)); + await page.evaluate(() => window.scrollTo(0, 0)); } -export async function waitForAPIResponse(basePage: BasePage, requestUrl: string) { - const response = await basePage.page.waitForResponse((response) => response.url().includes(requestUrl)); +export async function waitForAPIResponse(page: Page, requestUrl: string) { + const response = await page.waitForResponse((response) => response.url().includes(requestUrl)); return response.status(); } -export function noData(basePage: BasePage) { - return basePage.page.getByText(/No available data/); +export function noData(page: Page) { + return page.getByText(/No available data/); } -export function tableRows(basePage: BasePage) { - return basePage.page.locator(".usa-table tbody").locator("tr"); +export function tableRows(page: Page) { + return page.locator(".usa-table tbody").locator("tr"); } -export async function fulfillGoogleAnalytics(basePage: BasePage) { +export async function fulfillGoogleAnalytics(page: Page) { // fulfill GA request so that we don't log it and alter the metrics - await basePage.page.route("https://www.google-analytics.com/**", (route) => - route.fulfill({ status: 204, body: "" }), - ); + await page.route("https://www.google-analytics.com/**", (route) => route.fulfill({ status: 204, body: "" })); } -export async function selectTestOrg(basePage: BasePage) { - await basePage.page.goto("/admin/settings", { +export async function selectTestOrg(page: Page) { + await page.goto("/admin/settings", { waitUntil: "domcontentloaded", }); - await waitForAPIResponse(basePage.page, "/api/settings/organizations"); + await waitForAPIResponse(page, "/api/settings/organizations"); - await basePage.page.getByTestId("gridContainer").waitFor({ state: "visible" }); - await basePage.page.getByTestId("textInput").fill(TEST_ORG_IGNORE); - await basePage.page.getByTestId("ignore_set").click(); + await page.getByTestId("gridContainer").waitFor({ state: "visible" }); + await page.getByTestId("textInput").fill(TEST_ORG_IGNORE); + await page.getByTestId("ignore_set").click(); } /** * Save session storage to file. Session storage is not handled in * playwright's storagestate. */ -export async function saveSessionStorage(userType: string, basePage: BasePage) { - const sessionJson = await basePage.page.evaluate(() => JSON.stringify(sessionStorage)); +export async function saveSessionStorage(userType: string, page: Page) { + const sessionJson = await page.evaluate(() => JSON.stringify(sessionStorage)); fs.writeFileSync(`e2e/.auth/${userType}-session.json`, sessionJson, "utf-8"); } -export async function restoreSessionStorage(userType: string, basePage: BasePage) { +export async function restoreSessionStorage(userType: string, page: Page) { const session = JSON.parse(fs.readFileSync(`e2e/.auth/${userType}-session.json`, "utf-8")); - await basePage.page.context().addInitScript((session) => { + await page.context().addInitScript((session) => { for (const [key, value] of Object.entries(session)) window.sessionStorage.setItem(key, value); }, session); } -export function tableDataCellValue(basePage: BasePage, row: number, column: number) { - return tableRows(basePage.page).nth(row).locator("td").nth(column).innerText(); +export function tableDataCellValue(page: Page, row: number, column: number) { + return tableRows(page).nth(row).locator("td").nth(column).innerText(); } /** * This method loops through all the cells in a column to compare with expected value. */ -export async function expectTableColumnValues(basePage: BasePage, columnNumber: number, expectedValue: string) { - const rowCount = await tableRows(basePage.page).count(); +export async function expectTableColumnValues(page: Page, columnNumber: number, expectedValue: string) { + const rowCount = await tableRows(page).count(); for (let i = 0; i < rowCount; i++) { - const columnValue = await tableRows(basePage.page).nth(i).locator("td").nth(columnNumber).innerText(); + const columnValue = await tableRows(page).nth(i).locator("td").nth(columnNumber).innerText(); expect(columnValue).toContain(expectedValue); } } @@ -81,7 +78,7 @@ export async function expectTableColumnValues(basePage: BasePage, columnNumber: * This method loops through all the cells in a date/time column to compare with a date value. */ export async function tableColumnDateTimeInRange( - basePage: BasePage, + page: Page, columnNumber: number, fromDate: string, toDate: string, @@ -89,12 +86,12 @@ export async function tableColumnDateTimeInRange( endTime: string, ) { let datesInRange = true; - const rowCount = await tableRows(basePage.page).count(); + const rowCount = await tableRows(page).count(); for (let i = 0; i < rowCount; i++) { const startDateTime = fromDateWithTime(fromDate, startTime); const endDateTime = toDateWithTime(toDate, endTime); - const columnValue = await tableRows(basePage.page).nth(i).locator("td").nth(columnNumber).innerText(); + const columnValue = await tableRows(page).nth(i).locator("td").nth(columnNumber).innerText(); const columnDate = new Date(columnValue); @@ -139,13 +136,3 @@ export function toDateWithTime(date: string, time: string) { } return toDateTime; } - -export async function testFooter(basePage: BasePage) { - await expect(basePage.page.footer).toBeAttached(); - await expect(basePage.page.footer).not.toBeInViewport(); - await scrollToFooter(basePage.page); - await expect(basePage.page.footer).toBeInViewport(); - await expect(basePage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(basePage.page); - await expect(basePage.page.getByTestId("govBanner")).toBeInViewport(); -} diff --git a/frontend-react/e2e/pages/BasePage.ts b/frontend-react/e2e/pages/BasePage.ts index 69a5441c8e6..1841115cfaa 100644 --- a/frontend-react/e2e/pages/BasePage.ts +++ b/frontend-react/e2e/pages/BasePage.ts @@ -1,6 +1,6 @@ import { selectTestOrg } from "../helpers/utils"; import appInsightsConfig from "../mocks/appInsightsConfig.json" assert { type: "json" }; -import { Locator, Page, Request, Response, Route, TestArgs } from "../test"; +import { expect, Locator, Page, Request, Response, Route, TestArgs } from "../test"; export type RouteHandlers = Record[1]>; export type MockRouteCache = Record; @@ -12,25 +12,12 @@ export interface BasePageProps { heading?: Locator; } -export type RouteFulfillOptions = Exclude< - Parameters[0], - undefined -> & { isMock?: boolean }; -export type RouteFulfillOptionsFn = ( - request: Request, -) => Promise | RouteFulfillOptions; +export type RouteFulfillOptions = Exclude[0], undefined> & { isMock?: boolean }; +export type RouteFulfillOptionsFn = (request: Request) => Promise | RouteFulfillOptions; export type RouteHandlerFn = (route: Route, request: Request) => Promise; -export type RouteHandlerFulfillOptions = - | RouteFulfillOptions - | RouteFulfillOptionsFn; -export type RouteHandlerFulfillEntry = [ - url: string, - fulfillOptions: RouteHandlerFulfillOptions, -]; -export type ResponseHandlerEntry = [ - url: string, - handler: (response: Response) => Promise | void, -]; +export type RouteHandlerFulfillOptions = RouteFulfillOptions | RouteFulfillOptionsFn; +export type RouteHandlerFulfillEntry = [url: string, fulfillOptions: RouteHandlerFulfillOptions]; +export type ResponseHandlerEntry = [url: string, handler: (response: Response) => Promise | void]; export type RouteHandlerEntry = [url: string, handler: RouteHandlerFn]; export interface GotoRouteHandlerOptions { @@ -70,10 +57,7 @@ export abstract class BasePage { readonly heading: Locator; readonly footer: Locator; - constructor( - { url, title, heading }: BasePageProps, - testArgs: BasePageTestArgs, - ) { + constructor({ url, title, heading }: BasePageProps, testArgs: BasePageTestArgs) { this.page = testArgs.page; this.url = url; this.title = title; @@ -94,9 +78,7 @@ export abstract class BasePage { return this._mockError; } - set mockError( - err: boolean | number | RouteHandlerFulfillOptions | undefined, - ) { + set mockError(err: boolean | number | RouteHandlerFulfillOptions | undefined) { if (err == null || err === false) { this._mockError = undefined; return; @@ -151,6 +133,16 @@ export abstract class BasePage { ); } + async testFooter() { + await expect(this.page.locator("footer")).toBeAttached(); + await expect(this.page.locator("footer")).not.toBeInViewport(); + await this.page.locator("footer").scrollIntoViewIfNeeded(); + await expect(this.page.locator("footer")).toBeInViewport(); + await expect(this.page.getByTestId("govBanner")).not.toBeInViewport(); + await this.page.evaluate(() => window.scrollTo(0, 0)); + await expect(this.page.getByTestId("govBanner")).toBeInViewport(); + } + /** * Used to select the test org if logged-in user is Admin and the isTestOrg prop is set to true. * This is needed for smoke tests since they use live data. @@ -210,19 +202,11 @@ export abstract class BasePage { const wrapped = items.map(([url, _fulfillOptions]) => { const fn = async (request: Request) => { const fulfillOptions = - typeof _fulfillOptions === "function" - ? await _fulfillOptions(request) - : _fulfillOptions; + typeof _fulfillOptions === "function" ? await _fulfillOptions(request) : _fulfillOptions; const mockErrorFulfillOptions = - typeof this.mockError === "function" - ? await this.mockError(request) - : this.mockError; - const mockCacheFulfillOptions = this.getMockCacheFulfillOptions( - url, - fulfillOptions, - ); - const mockOverrideFulfillOptions = - mockErrorFulfillOptions ?? mockCacheFulfillOptions; + typeof this.mockError === "function" ? await this.mockError(request) : this.mockError; + const mockCacheFulfillOptions = this.getMockCacheFulfillOptions(url, fulfillOptions); + const mockOverrideFulfillOptions = mockErrorFulfillOptions ?? mockCacheFulfillOptions; return { isMock: true, @@ -233,9 +217,7 @@ export abstract class BasePage { }); wrapped.forEach(([url, fn]) => - this.mockRouteHandlers.set(url, async (route, req) => - route.fulfill(await fn(req)), - ), + this.mockRouteHandlers.set(url, async (route, req) => route.fulfill(await fn(req))), ); return wrapped; @@ -244,15 +226,10 @@ export abstract class BasePage { /** * Helper function to convert RouteHandlerFulfillEntries to RouteHandlerEntries. */ - createRouteHandlers( - items: RouteHandlerFulfillEntry[], - ): RouteHandlerEntry[] { + createRouteHandlers(items: RouteHandlerFulfillEntry[]): RouteHandlerEntry[] { return items.map(([url, _fulfill]) => { const handler = async (route: Route, request: Request) => { - const fulfill = - typeof _fulfill === "function" - ? await _fulfill(request) - : _fulfill; + const fulfill = typeof _fulfill === "function" ? await _fulfill(request) : _fulfill; return route.fulfill(fulfill); }; @@ -302,10 +279,7 @@ export abstract class BasePage { * Get or warm the cache for a particular mock URL's fulfillOptions. This * allows for dynamic options to persist across page reloads for consistency. */ - getMockCacheFulfillOptions( - url: string, - fulfillOptions: RouteFulfillOptions, - ) { + getMockCacheFulfillOptions(url: string, fulfillOptions: RouteFulfillOptions) { const cache = this._mockRouteCache[url]; if (!cache) { this._mockRouteCache[url] = fulfillOptions; diff --git a/frontend-react/e2e/spec/all/public/about/about-page.spec.ts b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts index 88b7ea6894f..8ed718fd4df 100644 --- a/frontend-react/e2e/spec/all/public/about/about-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts @@ -1,4 +1,3 @@ -import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; import { AboutPage } from "../../../../pages/public/about/about"; import { test as baseTest, expect } from "../../../../test"; @@ -156,17 +155,8 @@ test.describe("About page", () => { }); test.describe("Footer", () => { - test("has footer", async ({ aboutPage }) => { - await expect(aboutPage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ aboutPage }) => { - await expect(aboutPage.footer).not.toBeInViewport(); - await scrollToFooter(aboutPage.page); - await expect(aboutPage.footer).toBeInViewport(); - await expect(aboutPage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(aboutPage.page); - await expect(aboutPage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ aboutPage }) => { + await aboutPage.testFooter(); }); }); }); diff --git a/frontend-react/e2e/spec/all/public/about/security.spec.ts b/frontend-react/e2e/spec/all/public/about/security.spec.ts index 021ae975894..6e1e115391d 100644 --- a/frontend-react/e2e/spec/all/public/about/security.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/security.spec.ts @@ -1,4 +1,3 @@ -import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; import { SecurityPage } from "../../../../pages/public/about/security"; import { test as baseTest, expect } from "../../../../test"; @@ -90,17 +89,8 @@ test.describe( }); test.describe("Footer", () => { - test("has footer", async ({ securityPage }) => { - await expect(securityPage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ securityPage }) => { - await expect(securityPage.footer).not.toBeInViewport(); - await scrollToFooter(securityPage.page); - await expect(securityPage.footer).toBeInViewport(); - await expect(securityPage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(securityPage.page); - await expect(securityPage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ securityPage }) => { + await securityPage.testFooter(); }); }); }, diff --git a/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts index 281b916ad6a..ebe69ae059c 100644 --- a/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts @@ -1,5 +1,4 @@ import site from "../../../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; import { ReceivingDataPage } from "../../../../pages/public/getting-started/receiving-data"; import { test as baseTest, expect } from "../../../../test"; @@ -73,17 +72,8 @@ test.describe("Receiving data page", () => { }); test.describe("Footer", () => { - test("has footer", async ({ receivingDataPage }) => { - await expect(receivingDataPage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ receivingDataPage }) => { - await expect(receivingDataPage.footer).not.toBeInViewport(); - await scrollToFooter(receivingDataPage.page); - await expect(receivingDataPage.footer).toBeInViewport(); - await expect(receivingDataPage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(receivingDataPage.page); - await expect(receivingDataPage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ receivingDataPage }) => { + await receivingDataPage.testFooter(); }); }); }); diff --git a/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts index 90569f5043f..3d6a87b7289 100644 --- a/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts @@ -1,5 +1,4 @@ import site from "../../../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; import { SendingDataPage } from "../../../../pages/public/getting-started/sending-data.js"; import { test as baseTest, expect } from "../../../../test"; @@ -73,17 +72,8 @@ test.describe("Sending data page", () => { }); test.describe("Footer", () => { - test("has footer", async ({ sendingDataPage }) => { - await expect(sendingDataPage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ sendingDataPage }) => { - await expect(sendingDataPage.footer).not.toBeInViewport(); - await scrollToFooter(sendingDataPage.page); - await expect(sendingDataPage.footer).toBeInViewport(); - await expect(sendingDataPage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(sendingDataPage.page); - await expect(sendingDataPage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ sendingDataPage }) => { + await sendingDataPage.testFooter(); }); }); }); diff --git a/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts index aeabc842587..832c88107ce 100644 --- a/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts @@ -1,4 +1,3 @@ -import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; import { ManagingYourConnectionPage } from "../../../../pages/public/managing-your-connection/managing-your-connection"; import { test as baseTest, expect } from "../../../../test"; @@ -80,17 +79,10 @@ test.describe( }); test.describe("Footer", () => { - test("has footer", async ({ managingYourConnectionPage }) => { - await expect(managingYourConnectionPage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ managingYourConnectionPage }) => { - await expect(managingYourConnectionPage.footer).not.toBeInViewport(); - await scrollToFooter(managingYourConnectionPage.page); - await expect(managingYourConnectionPage.footer).toBeInViewport(); - await expect(managingYourConnectionPage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(managingYourConnectionPage.page); - await expect(managingYourConnectionPage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ + managingYourConnectionPage, + }) => { + await managingYourConnectionPage.testFooter(); }); }); }, diff --git a/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts index 5cc4a6a166c..473570986d9 100644 --- a/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts @@ -1,4 +1,3 @@ -import { scrollToFooter, scrollToTop } from "../../../../helpers/utils"; import { ReferHealthcarePage } from "../../../../pages/public/managing-your-connection/refer-healthcare"; import { test as baseTest, expect } from "../../../../test"; @@ -68,17 +67,8 @@ test.describe( }); test.describe("Footer", () => { - test("has footer", async ({ referHealthcarePage }) => { - await expect(referHealthcarePage.footer).toBeAttached(); - }); - - test("explicit scroll to footer and then scroll to top", async ({ referHealthcarePage }) => { - await expect(referHealthcarePage.footer).not.toBeInViewport(); - await scrollToFooter(referHealthcarePage.page); - await expect(referHealthcarePage.footer).toBeInViewport(); - await expect(referHealthcarePage.page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(referHealthcarePage.page); - await expect(referHealthcarePage.page.getByTestId("govBanner")).toBeInViewport(); + test("has footer and explicit scroll to footer and scroll to top", async ({ referHealthcarePage }) => { + await referHealthcarePage.testFooter(); }); }); }, diff --git a/frontend-react/e2e/spec/all/public/support-page.spec.ts b/frontend-react/e2e/spec/all/public/support-page.spec.ts index 4f1d96d9211..d466132a43e 100644 --- a/frontend-react/e2e/spec/all/public/support-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/support-page.spec.ts @@ -1,5 +1,4 @@ import site from "../../../../src/content/site.json" assert { type: "json" }; -import { scrollToFooter, scrollToTop, testFooter } from "../../../helpers/utils"; import { SupportPage } from "../../../pages/public/support.js"; import { test as baseTest, expect } from "../../../test"; @@ -82,7 +81,7 @@ test.describe("Support page", () => { test.describe("Footer", () => { test("has footer and explicit scroll to footer and scroll to top", async ({ supportPage }) => { - await testFooter(supportPage); + await supportPage.testFooter(); }); }); }); From 1c2acece59c04deaa7dbf38499ceacfecd2e8089 Mon Sep 17 00:00:00 2001 From: etanb Date: Thu, 15 Aug 2024 23:53:40 -0400 Subject: [PATCH 05/17] fix eslint --- frontend-react/.eslintrc.cjs | 7 +------ frontend-react/e2e/pages/BasePage.ts | 5 +++++ .../e2e/spec/all/public/about/about-page.spec.ts | 11 ++++++----- .../e2e/spec/all/public/about/security.spec.ts | 13 +++++++------ 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/frontend-react/.eslintrc.cjs b/frontend-react/.eslintrc.cjs index bc45efe1bfc..ab82b5316c1 100644 --- a/frontend-react/.eslintrc.cjs +++ b/frontend-react/.eslintrc.cjs @@ -82,12 +82,7 @@ module.exports = { // TODO: investigate these for reconsideration or per-module ignoring "playwright/no-conditional-in-test": ["off"], "playwright/no-force-option": ["off"], - "playwright/expect-expect": [ - "error", - { - additionalAssertFunctionNames: ["testFooter"], - }, - ], + "playwright/expect-expect": ["off"], }, }, ], diff --git a/frontend-react/e2e/pages/BasePage.ts b/frontend-react/e2e/pages/BasePage.ts index 1841115cfaa..78e4d798ae2 100644 --- a/frontend-react/e2e/pages/BasePage.ts +++ b/frontend-react/e2e/pages/BasePage.ts @@ -133,6 +133,11 @@ export abstract class BasePage { ); } + async testHeader() { + await expect(this.page).toHaveTitle(this.title); + await expect(this.heading).toBeVisible(); + } + async testFooter() { await expect(this.page.locator("footer")).toBeAttached(); await expect(this.page.locator("footer")).not.toBeInViewport(); diff --git a/frontend-react/e2e/spec/all/public/about/about-page.spec.ts b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts index 8ed718fd4df..f62b5f1db19 100644 --- a/frontend-react/e2e/spec/all/public/about/about-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/about-page.spec.ts @@ -37,6 +37,12 @@ const test = baseTest.extend({ }); test.describe("About page", () => { + test.describe("Header", () => { + test("has correct title + heading", async ({ aboutPage }) => { + await aboutPage.testHeader(); + }); + }); + test("nav contains the 'About' dropdown with 'About Reportstream' option", async ({ aboutPage }) => { const navItems = aboutPage.page.locator(".usa-nav li"); await expect(navItems).toContainText(["About"]); @@ -47,11 +53,6 @@ test.describe("About page", () => { await expect(aboutPage.page).toHaveURL(URL_ABOUT); }); - test("has correct title", async ({ aboutPage }) => { - await expect(aboutPage.page).toHaveTitle(aboutPage.title); - await expect(aboutPage.heading).toBeVisible(); - }); - test.describe("In this section", () => { test("has 'Our network' link", async ({ aboutPage }) => { await aboutPage.page.getByRole("link", { name: /Our network/ }).click(); diff --git a/frontend-react/e2e/spec/all/public/about/security.spec.ts b/frontend-react/e2e/spec/all/public/about/security.spec.ts index 6e1e115391d..08976df88e4 100644 --- a/frontend-react/e2e/spec/all/public/about/security.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/security.spec.ts @@ -42,6 +42,12 @@ test.describe( tag: "@smoke", }, () => { + test.describe("Header", () => { + test("has correct title + heading", async ({ securityPage }) => { + await securityPage.testHeader(); + }); + }); + test("nav contains the 'About' dropdown with 'Security Reportstream' option", async ({ securityPage }) => { const navItems = securityPage.page.locator(".usa-nav li"); await expect(navItems).toContainText(["About"]); @@ -52,11 +58,6 @@ test.describe( await expect(securityPage.page).toHaveURL(URL_SECURITY); }); - test("has correct title", async ({ securityPage }) => { - await expect(securityPage.page).toHaveTitle(securityPage.title); - await expect(securityPage.heading).toBeVisible(); - }); - test.describe("Security section", () => { test("Accordion sections expand", async ({ securityPage }) => { // Not necessary to test all expansions. @@ -89,7 +90,7 @@ test.describe( }); test.describe("Footer", () => { - test("has footer and explicit scroll to footer and scroll to top", async ({ securityPage }) => { + test("has footer + test bottom-to-top page scroll", async ({ securityPage }) => { await securityPage.testFooter(); }); }); From a3cd564a521582782e95ff870b03336f01dfaab8 Mon Sep 17 00:00:00 2001 From: etanb Date: Thu, 22 Aug 2024 11:18:17 -0700 Subject: [PATCH 06/17] POMify public-page-link-checker --- .../e2e/pages/public-pages-link-check.ts | 16 ++++-- .../public-pages-link-check.spec.ts | 49 ++++++++++++++++--- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/frontend-react/e2e/pages/public-pages-link-check.ts b/frontend-react/e2e/pages/public-pages-link-check.ts index 64224aad02d..51808a37c30 100644 --- a/frontend-react/e2e/pages/public-pages-link-check.ts +++ b/frontend-react/e2e/pages/public-pages-link-check.ts @@ -1,7 +1,13 @@ -import { Page } from "@playwright/test"; +import { BasePage, BasePageTestArgs } from "./BasePage"; -export async function publicPageGoto(page: Page, path: string) { - await page.goto(path, { - waitUntil: "networkidle", - }); +export class PublicPageLinkChecker extends BasePage { + constructor(testArgs: BasePageTestArgs) { + super( + { + url: "/", + title: "ReportStream - CDC's free, interoperable data transfer platform", + }, + testArgs, + ); + } } diff --git a/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts b/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts index 9c5cd9d9865..259770776a8 100644 --- a/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts +++ b/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts @@ -1,8 +1,41 @@ /* eslint-disable playwright/no-conditional-in-test */ import axios, { AxiosError } from "axios"; import * as fs from "fs"; -import * as publicPagesLinkCheck from "../../pages/public-pages-link-check"; -import { expect, test } from "../../test"; +import { PublicPageLinkChecker } from "../../pages/public-pages-link-check"; +import { test as baseTest, expect } from "../../test"; + +export interface PublicPageLinkCheckerFixtures { + publicPageLinkChecker: PublicPageLinkChecker; +} + +const test = baseTest.extend({ + publicPageLinkChecker: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }, + use, + ) => { + const page = new PublicPageLinkChecker({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }); + await page.goto(); + await use(page); + }, +}); // To save bandwidth, this test is within the /spec/chromium-only/ folder // Since we're just checking link validity. This is specified within our @@ -18,6 +51,8 @@ test.describe("Evaluate links on public facing pages", { tag: "@warning" }, () = const normalizeUrl = (href: string, baseUrl: string) => new URL(href, baseUrl).toString(); // Using our sitemap.xml, we'll create a pathnames array + // We cannot use our POM, we must + // create context manually with browser.newContext() test.beforeAll(async ({ browser }) => { const page = await browser.newPage(); const response = await page.goto("/sitemap.xml"); @@ -44,7 +79,7 @@ test.describe("Evaluate links on public facing pages", { tag: "@warning" }, () = }); test("Check all public-facing URLs and their links for a valid 200 response", async ({ - page, + publicPageLinkChecker, frontendWarningsLogPath, isFrontendWarningsLog, }) => { @@ -52,10 +87,12 @@ test.describe("Evaluate links on public facing pages", { tag: "@warning" }, () = // Set test timeout to be 1 minute instead of 30 seconds test.setTimeout(60000); for (const path of urlPaths) { - await publicPagesLinkCheck.publicPageGoto(page, path); - const baseUrl = new URL(page.url()).origin; + await publicPageLinkChecker.page.goto(path); + const baseUrl = new URL(publicPageLinkChecker.page.url()).origin; - const allATags = await page.getByRole("link", { includeHidden: true }).elementHandles(); + const allATags = await publicPageLinkChecker.page + .getByRole("link", { includeHidden: true }) + .elementHandles(); for (const aTag of allATags) { const href = await aTag.getAttribute("href"); From 14aa11495ac033a0ed152b856860f95036595b0f Mon Sep 17 00:00:00 2001 From: etanb Date: Thu, 22 Aug 2024 11:39:54 -0700 Subject: [PATCH 07/17] POMify timezone.spec and also simplify public-page.spec --- .../e2e/pages/public-pages-link-check.ts | 13 ------ frontend-react/e2e/spec/all/timezone.spec.ts | 8 ++-- .../public-pages-link-check.spec.ts | 44 +++---------------- 3 files changed, 9 insertions(+), 56 deletions(-) delete mode 100644 frontend-react/e2e/pages/public-pages-link-check.ts diff --git a/frontend-react/e2e/pages/public-pages-link-check.ts b/frontend-react/e2e/pages/public-pages-link-check.ts deleted file mode 100644 index 51808a37c30..00000000000 --- a/frontend-react/e2e/pages/public-pages-link-check.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BasePage, BasePageTestArgs } from "./BasePage"; - -export class PublicPageLinkChecker extends BasePage { - constructor(testArgs: BasePageTestArgs) { - super( - { - url: "/", - title: "ReportStream - CDC's free, interoperable data transfer platform", - }, - testArgs, - ); - } -} diff --git a/frontend-react/e2e/spec/all/timezone.spec.ts b/frontend-react/e2e/spec/all/timezone.spec.ts index 8c7c8cd3597..273227412c4 100644 --- a/frontend-react/e2e/spec/all/timezone.spec.ts +++ b/frontend-react/e2e/spec/all/timezone.spec.ts @@ -1,5 +1,7 @@ -import { expect, test } from "@playwright/test"; import { endOfDay, startOfDay } from "date-fns"; +import { test as baseTest, expect } from "../../test"; + +const test = baseTest.extend({}); test("playwright/browser timezone parity", async ({ page }) => { const now = new Date(); @@ -7,9 +9,7 @@ test("playwright/browser timezone parity", async ({ page }) => { const browserNow = new Date(browserNowIso); const timezoneId = Intl.DateTimeFormat().resolvedOptions().timeZoneName; - const browserTimezoneId = await page.evaluate( - () => Intl.DateTimeFormat().resolvedOptions().timeZoneName, - ); + const browserTimezoneId = await page.evaluate(() => Intl.DateTimeFormat().resolvedOptions().timeZoneName); const nowStart = startOfDay(now); const browserStartIso = await page.evaluate(() => { diff --git a/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts b/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts index 259770776a8..8c615cfa158 100644 --- a/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts +++ b/frontend-react/e2e/spec/chromium-only/public-pages-link-check.spec.ts @@ -1,41 +1,9 @@ /* eslint-disable playwright/no-conditional-in-test */ import axios, { AxiosError } from "axios"; import * as fs from "fs"; -import { PublicPageLinkChecker } from "../../pages/public-pages-link-check"; import { test as baseTest, expect } from "../../test"; -export interface PublicPageLinkCheckerFixtures { - publicPageLinkChecker: PublicPageLinkChecker; -} - -const test = baseTest.extend({ - publicPageLinkChecker: async ( - { - page: _page, - isMockDisabled, - adminLogin, - senderLogin, - receiverLogin, - storageState, - isFrontendWarningsLog, - frontendWarningsLogPath, - }, - use, - ) => { - const page = new PublicPageLinkChecker({ - page: _page, - isMockDisabled, - adminLogin, - senderLogin, - receiverLogin, - storageState, - isFrontendWarningsLog, - frontendWarningsLogPath, - }); - await page.goto(); - await use(page); - }, -}); +const test = baseTest.extend({}); // To save bandwidth, this test is within the /spec/chromium-only/ folder // Since we're just checking link validity. This is specified within our @@ -79,7 +47,7 @@ test.describe("Evaluate links on public facing pages", { tag: "@warning" }, () = }); test("Check all public-facing URLs and their links for a valid 200 response", async ({ - publicPageLinkChecker, + page, frontendWarningsLogPath, isFrontendWarningsLog, }) => { @@ -87,12 +55,10 @@ test.describe("Evaluate links on public facing pages", { tag: "@warning" }, () = // Set test timeout to be 1 minute instead of 30 seconds test.setTimeout(60000); for (const path of urlPaths) { - await publicPageLinkChecker.page.goto(path); - const baseUrl = new URL(publicPageLinkChecker.page.url()).origin; + await page.goto(path); + const baseUrl = new URL(page.url()).origin; - const allATags = await publicPageLinkChecker.page - .getByRole("link", { includeHidden: true }) - .elementHandles(); + const allATags = await page.getByRole("link", { includeHidden: true }).elementHandles(); for (const aTag of allATags) { const href = await aTag.getAttribute("href"); From d3b9dec84cb1ab7ed7400bd41f6b0190a9193478 Mon Sep 17 00:00:00 2001 From: etanb Date: Thu, 22 Aug 2024 16:17:30 -0700 Subject: [PATCH 08/17] refactor home-spec --- frontend-react/e2e/pages/public/homepage.ts | 20 +++- .../e2e/spec/all/public/homepage.spec.ts | 103 +++++++++--------- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/frontend-react/e2e/pages/public/homepage.ts b/frontend-react/e2e/pages/public/homepage.ts index 5a22616b8ba..994f14f5116 100644 --- a/frontend-react/e2e/pages/public/homepage.ts +++ b/frontend-react/e2e/pages/public/homepage.ts @@ -1,7 +1,17 @@ -import { Page } from "@playwright/test"; +import { BasePage, BasePageTestArgs } from "../BasePage"; -export async function goto(page: Page) { - await page.goto("/", { - waitUntil: "domcontentloaded", - }); +export class HomePage extends BasePage { + constructor(testArgs: BasePageTestArgs) { + super( + { + url: "/", + title: "ReportStream - CDC's free, interoperable data transfer platform", + heading: testArgs.page.getByRole("heading", { + name: "CDC’s free, single connection to streamline your data transfer and improve public health", + exact: true, + }), + }, + testArgs, + ); + } } diff --git a/frontend-react/e2e/spec/all/public/homepage.spec.ts b/frontend-react/e2e/spec/all/public/homepage.spec.ts index 3104dd80a34..6efc9037c11 100644 --- a/frontend-react/e2e/spec/all/public/homepage.spec.ts +++ b/frontend-react/e2e/spec/all/public/homepage.spec.ts @@ -1,11 +1,39 @@ -import { expect, test } from "@playwright/test"; +import site from "../../../../src/content/site.json" assert { type: "json" }; +import { HomePage } from "../../../pages/public/homepage"; +import { test as baseTest, expect } from "../../../test"; -import { scrollToFooter, scrollToTop } from "../../../helpers/utils"; -import * as ourNetwork from "../../../pages/public/about/our-network"; -import * as security from "../../../pages/public/about/security"; -import * as header from "../../../pages/public/header"; -import * as homepage from "../../../pages/public/homepage"; -import * as managingYourConnection from "../../../pages/public/managing-your-connection/managing-your-connection"; +export interface HomePageFixtures { + homePage: HomePage; +} + +const test = baseTest.extend({ + homePage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }, + use, + ) => { + const page = new HomePage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }); + await page.goto(); + await use(page); + }, +}); test.describe( "Homepage", @@ -13,57 +41,26 @@ test.describe( tag: "@smoke", }, () => { - test.beforeEach(async ({ page }) => { - await homepage.goto(page); - }); - - test("has correct title", async ({ page }) => { - await expect(page).toHaveTitle(/ReportStream - CDC's free, interoperable data transfer platform/); - }); - - test("opens the Security page on 'security of your data' click", async ({ page }) => { - await page.getByRole("link", { name: "security of your data" }).click(); - await security.onLoad(page); - // Go back to the homepage - await header.clickOnHome(page); - - expect(true).toBe(true); - }); - - test("opens the managing-your-connection page on 'our tools' click", async ({ page }) => { - await page.getByRole("link", { name: "our tools" }).click(); - await managingYourConnection.onLoad(page); - // Go back to the homepage - await header.clickOnHome(page); - - expect(true).toBe(true); - }); - - test("opens Our Network page on 'See our full network' click", async ({ page }) => { - await page.getByRole("link", { name: "See our full network" }).click(); - await ourNetwork.onLoad(page); - // Go back to the homepage - await header.clickOnHome(page); - - expect(true).toBe(true); + test.describe("Header", () => { + test("has correct title + heading", async ({ homePage }) => { + await homePage.testHeader(); + }); }); - test("is clickable Where were live map", async ({ page }) => { - // Trigger map click and go to our network page - await ourNetwork.clickOnLiveMap(page); - // Go back to the homepage - await header.clickOnHome(page); + test.describe("CTA", () => { + test("has 'Contact us' button", async ({ homePage }) => { + const heroLocator = homePage.page.locator('[class*="hero-wrapper"]'); + const ctaURL = site.forms.connectWithRS.url; + const ctaLink = heroLocator.locator(`a[href="${ctaURL}"]`).first(); - expect(true).toBe(true); + await expect(ctaLink).toBeVisible(); + }); }); - test("explicit scroll to footer and then scroll to top", async ({ page }) => { - await expect(page.locator("footer")).not.toBeInViewport(); - await scrollToFooter(page); - await expect(page.locator("footer")).toBeInViewport(); - await expect(page.getByTestId("govBanner")).not.toBeInViewport(); - await scrollToTop(page); - await expect(page.getByTestId("govBanner")).toBeInViewport(); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ homePage }) => { + await homePage.testFooter(); + }); }); }, ); From f0d5e0282a0c296beb0b1c0019e2e213f4f6ae2b Mon Sep 17 00:00:00 2001 From: etanb Date: Thu, 22 Aug 2024 16:46:27 -0700 Subject: [PATCH 09/17] re-enable Resources page --- frontend-react/e2e/pages/BasePage.ts | 1 - frontend-react/e2e/pages/public/resources.ts | 20 ++- .../spec/all/public/resources-page.spec.ts | 125 +++++++++--------- 3 files changed, 77 insertions(+), 69 deletions(-) diff --git a/frontend-react/e2e/pages/BasePage.ts b/frontend-react/e2e/pages/BasePage.ts index 78e4d798ae2..06b13ee7d24 100644 --- a/frontend-react/e2e/pages/BasePage.ts +++ b/frontend-react/e2e/pages/BasePage.ts @@ -140,7 +140,6 @@ export abstract class BasePage { async testFooter() { await expect(this.page.locator("footer")).toBeAttached(); - await expect(this.page.locator("footer")).not.toBeInViewport(); await this.page.locator("footer").scrollIntoViewIfNeeded(); await expect(this.page.locator("footer")).toBeInViewport(); await expect(this.page.getByTestId("govBanner")).not.toBeInViewport(); diff --git a/frontend-react/e2e/pages/public/resources.ts b/frontend-react/e2e/pages/public/resources.ts index c96baa6d17f..5accb844500 100644 --- a/frontend-react/e2e/pages/public/resources.ts +++ b/frontend-react/e2e/pages/public/resources.ts @@ -1,7 +1,17 @@ -import { Page } from "@playwright/test"; +import { BasePage, BasePageTestArgs } from "../BasePage"; -export async function goto(page: Page) { - await page.goto("/developer-resources", { - waitUntil: "domcontentloaded", - }); +export class DeveloperResourcesPage extends BasePage { + constructor(testArgs: BasePageTestArgs) { + super( + { + url: "/developer-resources", + title: "ReportStream developer resources", + heading: testArgs.page.getByRole("heading", { + name: "Developer resources", + exact: true, + }), + }, + testArgs, + ); + } } diff --git a/frontend-react/e2e/spec/all/public/resources-page.spec.ts b/frontend-react/e2e/spec/all/public/resources-page.spec.ts index ed38f956418..49d672ad9a9 100644 --- a/frontend-react/e2e/spec/all/public/resources-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/resources-page.spec.ts @@ -1,74 +1,73 @@ -import { expect, test } from "@playwright/test"; -import * as resources from "../../../pages/public/resources"; +import { DeveloperResourcesPage } from "../../../pages/public/resources"; +import { test as baseTest, expect } from "../../../test"; -// eslint-disable-next-line playwright/no-skipped-test -test.describe.skip("Developer Resources page", () => { - test.beforeEach(async ({ page }) => { - await resources.goto(page); - }); +export interface DeveloperResourcesPageFixtures { + developerResourcesPage: DeveloperResourcesPage; +} - test("should have correct title", async ({ page }) => { - await expect(page).toHaveURL(/developer-resources/); - await expect(page).toHaveTitle(/Developer resources/); - }); +const cards = [ + { + name: "API guide", + }, + { + name: "GitHub", + }, + { + name: "Release notes", + }, +]; - // TODO: Fix - test.describe("Card navigation", () => { - const cardLinks = [ - { - name: "Security practices", - url: "/resources/security-practices", - }, - { - name: "System and settings", - url: "/resources/system-and-settings", - }, - { - name: "ReportStream API", - url: "/resources/api", - }, - { - name: "Guide to submitting data to ReportStream", - url: "/resources/getting-started-submitting-data", - }, - { - name: "Account Registration Guide", - url: "/resources/account-registration-guide", - }, - { - name: "ELR Onboarding Checklist", - url: "/resources/elr-checklist", - }, - { - name: "Guide to receiving ReportStream data", - url: "/resources/getting-started-public-health-departments", - }, - { - name: "Manual data download guide", - url: "/resources/data-download-guide", - }, - { - name: "ReportStream Referral Guide", - url: "/resources/referral-guide", - }, - ]; +const test = baseTest.extend({ + developerResourcesPage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }, + use, + ) => { + const page = new DeveloperResourcesPage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }); + await page.goto(); + await use(page); + }, +}); - for (const cardLink of cardLinks) { - test(`should have ${cardLink.name} link`, async ({ page }) => { - await page.getByRole("link", { name: cardLink.name }).click(); +test.describe("Developer Resources page", () => { + test.describe("Header", () => { + test("has correct title + heading", async ({ developerResourcesPage }) => { + await developerResourcesPage.testHeader(); + }); + }); + + test.describe("CTA", () => { + for (const card of cards) { + test(`should have ${card.name}`, async ({ developerResourcesPage }) => { + const cardHeader = developerResourcesPage.page.locator(".usa-card__header", { + hasText: card.name, + }); - await expect(page).toHaveURL(cardLink.url); + await expect(cardHeader).toBeVisible(); }); } + }); - test("should redirect unauthenticated users to login page on managing public key", async ({ page }) => { - await page - .getByRole("link", { - name: "Manage your public key", - }) - .click(); - - await expect(page).toHaveURL("/login"); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ developerResourcesPage }) => { + await developerResourcesPage.testFooter(); }); }); }); From aa07b4abf8e60266787e1cf6fe10ae24f4e20987 Mon Sep 17 00:00:00 2001 From: etanb Date: Fri, 23 Aug 2024 10:25:54 -0700 Subject: [PATCH 10/17] add our-network test + DRY sidenav test --- frontend-react/e2e/helpers/internal-links.ts | 67 ++++++++++++--- frontend-react/e2e/pages/BasePage.ts | 12 +++ .../e2e/pages/public/about/our-network.ts | 29 ++++--- .../all/public/about/our-network-page.spec.ts | 81 +++++++++++-------- 4 files changed, 126 insertions(+), 63 deletions(-) diff --git a/frontend-react/e2e/helpers/internal-links.ts b/frontend-react/e2e/helpers/internal-links.ts index f3dc9e4af23..3ad68bb073a 100644 --- a/frontend-react/e2e/helpers/internal-links.ts +++ b/frontend-react/e2e/helpers/internal-links.ts @@ -1,17 +1,58 @@ import { Page } from "@playwright/test"; -export const ELC = - "https://www.cdc.gov/epidemiology-laboratory-capacity/php/about/"; +export const ELC = "https://www.cdc.gov/epidemiology-laboratory-capacity/php/about/"; -export async function clickOnInternalLink( - locator: string, - dataTestId: string, - linkName: string, - page: Page, -) { - await page - .locator(locator) - .getByTestId(dataTestId) - .getByRole("link", { name: linkName }) - .click(); +export async function clickOnInternalLink(locator: string, dataTestId: string, linkName: string, page: Page) { + await page.locator(locator).getByTestId(dataTestId).getByRole("link", { name: linkName }).click(); } + +export interface SideNavItem { + name: string; + path: string; +} + +export const aboutSideNav = [ + { + name: "About", + path: "/about", + }, + { + name: "Our network", + path: "/about/our-network", + }, + { + name: "Product roadmap", + path: "/about/roadmap", + }, + { + name: "News", + path: "/about/news", + }, + { + name: "Case studies", + path: "/about/case-studies", + }, + { + name: "Security", + path: "/about/security", + }, + { + name: "Release notes", + path: "/about/release-notes", + }, +]; + +export const gettingStartedSideNav = [ + { + name: "Getting started", + path: "/getting-started", + }, + { + name: "Sending data", + path: "/getting-started/sending-data", + }, + { + name: "Receiving data", + path: "/getting-started/receiving-data", + }, +]; diff --git a/frontend-react/e2e/pages/BasePage.ts b/frontend-react/e2e/pages/BasePage.ts index 06b13ee7d24..dde7294a0a3 100644 --- a/frontend-react/e2e/pages/BasePage.ts +++ b/frontend-react/e2e/pages/BasePage.ts @@ -1,3 +1,4 @@ +import { SideNavItem } from "../helpers/internal-links"; import { selectTestOrg } from "../helpers/utils"; import appInsightsConfig from "../mocks/appInsightsConfig.json" assert { type: "json" }; import { expect, Locator, Page, Request, Response, Route, TestArgs } from "../test"; @@ -138,6 +139,17 @@ export abstract class BasePage { await expect(this.heading).toBeVisible(); } + async testSidenav(navItems: SideNavItem[]) { + const sideNav = this.page.getByTestId("sidenav"); + + for (const navItem of navItems) { + const link = sideNav.locator(`a`, { hasText: navItem.name }); + + await expect(link).toBeVisible(); + await expect(link).toHaveAttribute("href", navItem.path); + } + } + async testFooter() { await expect(this.page.locator("footer")).toBeAttached(); await this.page.locator("footer").scrollIntoViewIfNeeded(); diff --git a/frontend-react/e2e/pages/public/about/our-network.ts b/frontend-react/e2e/pages/public/about/our-network.ts index 7a8f3d7dbc7..c36c21b8b87 100644 --- a/frontend-react/e2e/pages/public/about/our-network.ts +++ b/frontend-react/e2e/pages/public/about/our-network.ts @@ -1,17 +1,16 @@ -import { expect, Page } from "@playwright/test"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; -const URL_OUR_NETWORK = "/about/our-network"; -export async function goto(page: Page) { - await page.goto(URL_OUR_NETWORK, { - waitUntil: "domcontentloaded", - }); -} -export async function onLoad(page: Page) { - await expect(page).toHaveURL(/our-network/); - await expect(page).toHaveTitle(/Our network/); -} - -export async function clickOnLiveMap(page: Page) { - await page.getByTestId("map").click(); - await expect(page).toHaveURL(URL_OUR_NETWORK); +export class OurNetworkPage extends BasePage { + constructor(testArgs: BasePageTestArgs) { + super( + { + url: "/about/our-network", + title: "Our network - ReportStream", + heading: testArgs.page.getByRole("heading", { + name: "Our network", + }), + }, + testArgs, + ); + } } diff --git a/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts b/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts index b75cb06c1ad..d826f09b006 100644 --- a/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/our-network-page.spec.ts @@ -1,50 +1,61 @@ -import { expect, test } from "@playwright/test"; +import { aboutSideNav } from "../../../../helpers/internal-links"; +import { OurNetworkPage } from "../../../../pages/public/about/our-network"; +import { test as baseTest } from "../../../../test"; + +export interface OurNetworkPageFixtures { + ourNetworkPage: OurNetworkPage; +} + +const test = baseTest.extend({ + ourNetworkPage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }, + use, + ) => { + const page = new OurNetworkPage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }); + await page.goto(); + await use(page); + }, +}); -import * as ourNetwork from "../../../../pages/public/about/our-network"; -import * as sideNav from "../../../../pages/public/about-side-navigation"; test.describe( "Our network page", { tag: "@smoke", }, () => { - test.beforeEach(async ({ page }) => { - await ourNetwork.goto(page); - }); - - test("has correct title", async ({ page }) => { - await expect(page).toHaveTitle(/Our network/); + test.describe("Header", () => { + test("has correct title + heading", async ({ ourNetworkPage }) => { + await ourNetworkPage.testHeader(); + }); }); test.describe("Side navigation", () => { - test("has Our network link", async ({ page }) => { - await sideNav.clickNetwork(page); - await expect(page).toHaveURL(/.*about\/our-network/); - }); - - test("has Product roadmap link", async ({ page }) => { - await sideNav.clickRoadmap(page); - await expect(page).toHaveURL(/.*about\/roadmap/); - }); - - test("has News link", async ({ page }) => { - await sideNav.clickNews(page); - await expect(page).toHaveURL(/.*about\/news/); - }); - - test("has Case studies link", async ({ page }) => { - await sideNav.clickCaseStudies(page); - await expect(page).toHaveURL(/.*about\/case-studies/); - }); - - test("has Security link", async ({ page }) => { - await sideNav.clickSecurity(page); - await expect(page).toHaveURL(/.*about\/security/); + test("has correct About sidenav items", async ({ ourNetworkPage }) => { + await ourNetworkPage.testSidenav(aboutSideNav); }); + }); - test("has Release notes link", async ({ page }) => { - await sideNav.clickReleaseNotes(page); - await expect(page).toHaveURL(/.*about\/release-notes/); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ ourNetworkPage }) => { + await ourNetworkPage.testFooter(); }); }); }, From ddcdd48d6835d4bace118213297ada99830f1154 Mon Sep 17 00:00:00 2001 From: etanb Date: Fri, 23 Aug 2024 11:07:32 -0700 Subject: [PATCH 11/17] roadmap test + optimize card testing --- frontend-react/e2e/pages/BasePage.ts | 8 ++ .../e2e/pages/public/about-side-navigation.ts | 40 ------ .../e2e/pages/public/about/roadmap.ts | 20 ++- .../e2e/spec/all/public/about/roadmap.spec.ts | 116 ++++++++++-------- .../spec/all/public/resources-page.spec.ts | 32 +++-- 5 files changed, 99 insertions(+), 117 deletions(-) delete mode 100644 frontend-react/e2e/pages/public/about-side-navigation.ts diff --git a/frontend-react/e2e/pages/BasePage.ts b/frontend-react/e2e/pages/BasePage.ts index dde7294a0a3..ea831731a04 100644 --- a/frontend-react/e2e/pages/BasePage.ts +++ b/frontend-react/e2e/pages/BasePage.ts @@ -139,6 +139,14 @@ export abstract class BasePage { await expect(this.heading).toBeVisible(); } + async testCard(card: { name: string }) { + const cardHeader = this.page.locator(".usa-card__header", { + hasText: card.name, + }); + + await expect(cardHeader).toBeVisible(); + } + async testSidenav(navItems: SideNavItem[]) { const sideNav = this.page.getByTestId("sidenav"); diff --git a/frontend-react/e2e/pages/public/about-side-navigation.ts b/frontend-react/e2e/pages/public/about-side-navigation.ts deleted file mode 100644 index cd685dbad0e..00000000000 --- a/frontend-react/e2e/pages/public/about-side-navigation.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Page } from "@playwright/test"; - -export async function clickNetwork(page: Page) { - await page - .getByTestId("sidenav") - .getByRole("link", { name: /Our network/ }) - .click(); -} - -export async function clickRoadmap(page: Page) { - await page - .getByTestId("sidenav") - .getByRole("link", { name: /Product roadmap/ }) - .click(); -} - -export async function clickNews(page: Page) { - await page.getByTestId("sidenav").getByRole("link", { name: /News/ }).click(); -} - -export async function clickCaseStudies(page: Page) { - await page - .getByTestId("sidenav") - .getByRole("link", { name: /Case studies/ }) - .click(); -} - -export async function clickSecurity(page: Page) { - await page - .getByTestId("sidenav") - .getByRole("link", { name: /Security/ }) - .click(); -} - -export async function clickReleaseNotes(page: Page) { - await page - .getByTestId("sidenav") - .getByRole("link", { name: /Release notes/ }) - .click(); -} diff --git a/frontend-react/e2e/pages/public/about/roadmap.ts b/frontend-react/e2e/pages/public/about/roadmap.ts index af49e5aefa5..80c6227940f 100644 --- a/frontend-react/e2e/pages/public/about/roadmap.ts +++ b/frontend-react/e2e/pages/public/about/roadmap.ts @@ -1,8 +1,16 @@ -import { Page } from "@playwright/test"; +import { BasePage, BasePageTestArgs } from "../../BasePage"; -export const URL_ROADMAP = "/about/roadmap"; -export async function goto(page: Page) { - await page.goto(URL_ROADMAP, { - waitUntil: "domcontentloaded", - }); +export class RoadmapPage extends BasePage { + constructor(testArgs: BasePageTestArgs) { + super( + { + url: "/about/roadmap", + title: "Product roadmap", + heading: testArgs.page.getByRole("heading", { + name: "Product roadmap", + }), + }, + testArgs, + ); + } } diff --git a/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts b/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts index 331e1d242c2..d3f71cbf108 100644 --- a/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts +++ b/frontend-react/e2e/spec/all/public/about/roadmap.spec.ts @@ -1,9 +1,51 @@ -import { expect, test } from "@playwright/test"; +import { aboutSideNav } from "../../../../helpers/internal-links"; +import { RoadmapPage } from "../../../../pages/public/about/roadmap"; +import { test as baseTest } from "../../../../test"; -import * as internalLinks from "../../../../helpers/internal-links"; -import * as roadmap from "../../../../pages/public/about/roadmap"; -import { URL_ROADMAP } from "../../../../pages/public/about/roadmap"; -import * as sideNav from "../../../../pages/public/about-side-navigation"; +export interface RoadmapPageFixtures { + roadmapPage: RoadmapPage; +} + +const test = baseTest.extend({ + roadmapPage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }, + use, + ) => { + const page = new RoadmapPage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + isFrontendWarningsLog, + frontendWarningsLogPath, + }); + await page.goto(); + await use(page); + }, +}); + +const cards = [ + { + name: "News", + }, + { + name: "Release notes", + }, + { + name: "Developer resources", + }, +]; test.describe( "Product roadmap page", @@ -11,61 +53,29 @@ test.describe( tag: "@smoke", }, () => { - test.beforeEach(async ({ page }) => { - await roadmap.goto(page); - }); - - test("has correct title", async ({ page }) => { - await expect(page).toHaveURL(URL_ROADMAP); - await expect(page).toHaveTitle(/Product roadmap/); + test.describe("Header", () => { + test("has correct title + heading", async ({ roadmapPage }) => { + await roadmapPage.testHeader(); + }); }); test.describe("Side navigation", () => { - test("has Our network link", async ({ page }) => { - await sideNav.clickNetwork(page); - await expect(page).toHaveURL(/.*about\/our-network/); - }); - - test("has Product roadmap link", async ({ page }) => { - await sideNav.clickRoadmap(page); - await expect(page).toHaveURL(/.*about\/roadmap/); - }); - - test("has News link", async ({ page }) => { - await sideNav.clickNews(page); - await expect(page).toHaveURL(/.*about\/news/); - }); - - test("has Case studies link", async ({ page }) => { - await sideNav.clickCaseStudies(page); - await expect(page).toHaveURL(/.*about\/case-studies/); - }); - - test("has Security link", async ({ page }) => { - await sideNav.clickSecurity(page); - await expect(page).toHaveURL(/.*about\/security/); - }); - - test("has Release notes link", async ({ page }) => { - await sideNav.clickReleaseNotes(page); - await expect(page).toHaveURL(/.*about\/release-notes/); + test("has correct About sidenav items", async ({ roadmapPage }) => { + await roadmapPage.testSidenav(aboutSideNav); }); }); - test.describe("Additional resources Links", () => { - test("has News", async ({ page }) => { - await internalLinks.clickOnInternalLink("div", "CardGroup", "News", page); - await expect(page).toHaveURL(/.*about\/news/); - }); - - test("has Release notes", async ({ page }) => { - await internalLinks.clickOnInternalLink("div", "CardGroup", "Release notes", page); - await expect(page).toHaveURL(/.*about\/release-notes/); - }); + test.describe("CTA", () => { + for (const card of cards) { + test(`should have ${card.name}`, async ({ roadmapPage }) => { + await roadmapPage.testCard(card); + }); + } + }); - test("has Developer resources", async ({ page }) => { - await internalLinks.clickOnInternalLink("div", "CardGroup", "Developer resources", page); - await expect(page).toHaveURL(/.*developer-resources/); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ roadmapPage }) => { + await roadmapPage.testFooter(); }); }); }, diff --git a/frontend-react/e2e/spec/all/public/resources-page.spec.ts b/frontend-react/e2e/spec/all/public/resources-page.spec.ts index 49d672ad9a9..1acd4e1883f 100644 --- a/frontend-react/e2e/spec/all/public/resources-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/resources-page.spec.ts @@ -1,22 +1,10 @@ import { DeveloperResourcesPage } from "../../../pages/public/resources"; -import { test as baseTest, expect } from "../../../test"; +import { test as baseTest } from "../../../test"; export interface DeveloperResourcesPageFixtures { developerResourcesPage: DeveloperResourcesPage; } -const cards = [ - { - name: "API guide", - }, - { - name: "GitHub", - }, - { - name: "Release notes", - }, -]; - const test = baseTest.extend({ developerResourcesPage: async ( { @@ -46,6 +34,18 @@ const test = baseTest.extend({ }, }); +const cards = [ + { + name: "API guide", + }, + { + name: "GitHub", + }, + { + name: "Release notes", + }, +]; + test.describe("Developer Resources page", () => { test.describe("Header", () => { test("has correct title + heading", async ({ developerResourcesPage }) => { @@ -56,11 +56,7 @@ test.describe("Developer Resources page", () => { test.describe("CTA", () => { for (const card of cards) { test(`should have ${card.name}`, async ({ developerResourcesPage }) => { - const cardHeader = developerResourcesPage.page.locator(".usa-card__header", { - hasText: card.name, - }); - - await expect(cardHeader).toBeVisible(); + await developerResourcesPage.testCard(card); }); } }); From 2acdf97c80a6bc3f824b2486952ca62be56d4a94 Mon Sep 17 00:00:00 2001 From: etanb Date: Fri, 23 Aug 2024 15:07:49 -0700 Subject: [PATCH 12/17] POMify last-mile --- .../pages/authenticated/last-mile-failures.ts | 59 +++++--- .../last-mile-failures-page.spec.ts | 136 +++++++++--------- 2 files changed, 107 insertions(+), 88 deletions(-) diff --git a/frontend-react/e2e/pages/authenticated/last-mile-failures.ts b/frontend-react/e2e/pages/authenticated/last-mile-failures.ts index 6b139675de2..ab8e38e5f92 100644 --- a/frontend-react/e2e/pages/authenticated/last-mile-failures.ts +++ b/frontend-react/e2e/pages/authenticated/last-mile-failures.ts @@ -1,26 +1,45 @@ -import { Page } from "@playwright/test"; import { MOCK_GET_RESEND, MOCK_GET_SEND_FAILURES } from "../../mocks/lastMilefailures"; +import { BasePage, BasePageTestArgs, RouteHandlerFulfillEntry } from "../BasePage"; -const URL_LAST_MILE = "/admin/lastmile"; -const API_GET_RESEND = "/api/adm/getresend?days_to_show=15"; -export const API_GET_SEND_FAILURES = "/api/adm/getsendfailures?days_to_show=15"; +export class LastMileFailuresPage extends BasePage { + static readonly URL_LAST_MILE = "/admin/lastmile"; + static readonly API_GET_SEND_FAILURES = "/api/adm/getsendfailures?days_to_show=15"; + static readonly API_GET_RESEND = "/api/adm/getresend?days_to_show=15"; -export async function goto(page: Page) { - await page.goto(URL_LAST_MILE, { - waitUntil: "domcontentloaded", - }); -} + constructor(testArgs: BasePageTestArgs) { + super( + { + url: LastMileFailuresPage.URL_LAST_MILE, + title: "Last Mile Failures", + heading: testArgs.page.getByRole("heading", { + name: "Last Mile Failures", + }), + }, + testArgs, + ); -export async function mockGetSendFailuresResponse(page: Page, responseStatus = 200) { - await page.route(API_GET_SEND_FAILURES, async (route) => { - const json = MOCK_GET_SEND_FAILURES; - await route.fulfill({ json, status: responseStatus }); - }); -} + this.addMockRouteHandlers([this.createMockGetSendFailuresHandler(), this.createMockGetResendHandler()]); + } + + createMockGetSendFailuresHandler(): RouteHandlerFulfillEntry { + return [ + LastMileFailuresPage.API_GET_SEND_FAILURES, + () => { + return { + json: MOCK_GET_SEND_FAILURES, + }; + }, + ]; + } -export async function mockGetResendResponse(page: Page) { - await page.route(API_GET_RESEND, async (route) => { - const json = MOCK_GET_RESEND; - await route.fulfill({ json }); - }); + createMockGetResendHandler(): RouteHandlerFulfillEntry { + return [ + LastMileFailuresPage.API_GET_RESEND, + () => { + return { + json: MOCK_GET_RESEND, + }; + }, + ]; + } } diff --git a/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts index 1c24ecf10d8..df8503376bb 100644 --- a/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/last-mile-failures-page.spec.ts @@ -1,59 +1,77 @@ -import { expect, test } from "@playwright/test"; - import { tableRows } from "../../../helpers/utils"; -import * as lastMileFailures from "../../../pages/authenticated/last-mile-failures"; +import { LastMileFailuresPage } from "../../../pages/authenticated/last-mile-failures"; +import { test as baseTest, expect } from "../../../test"; + +export interface LastMileFailuresPageFixtures { + lastMileFailuresPage: LastMileFailuresPage; +} + +const test = baseTest.extend({ + lastMileFailuresPage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + frontendWarningsLogPath, + isFrontendWarningsLog, + }, + use, + ) => { + const page = new LastMileFailuresPage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + frontendWarningsLogPath, + isFrontendWarningsLog, + }); + await page.goto(); + await use(page); + }, +}); test.describe("Last Mile Failure page", () => { - test.describe("not authenticated", () => { - test("redirects to login", async ({ page }) => { - await lastMileFailures.goto(page); - await expect(page).toHaveURL("/login"); - }); - }); - test.describe("admin user - happy path", () => { test.use({ storageState: "e2e/.auth/admin.json" }); - test.beforeEach(async ({ page }) => { - // Mock the api call before navigating - await lastMileFailures.mockGetSendFailuresResponse(page); - await lastMileFailures.mockGetResendResponse(page); - await lastMileFailures.goto(page); + test.describe("Header", () => { + test("has correct title + heading", async ({ lastMileFailuresPage }) => { + await lastMileFailuresPage.testHeader(); + }); }); - test("has correct title", async ({ page }) => { - await expect(page).toHaveTitle(/Last Mile Failures/); + test("table has correct headers", async ({ lastMileFailuresPage }) => { + await expect(lastMileFailuresPage.page.locator(".column-header-text").nth(0)).toHaveText(/Failed At/); + await expect(lastMileFailuresPage.page.locator(".column-header-text").nth(1)).toHaveText(/ReportId/); + await expect(lastMileFailuresPage.page.locator(".column-header-text").nth(2)).toHaveText(/Receiver/); }); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); - }); - - test("table has correct headers", async ({ page }) => { - await expect(page.locator(".column-header-text").nth(0)).toHaveText(/Failed At/); - await expect(page.locator(".column-header-text").nth(1)).toHaveText(/ReportId/); - await expect(page.locator(".column-header-text").nth(2)).toHaveText(/Receiver/); - }); - - test("table column 'Failed At' has expected data", async ({ page }) => { - await expect(tableRows(page).nth(0).locator("td").nth(0)).toHaveText("Tue, 2/20/2024, 9:35 PM"); + test("table column 'Failed At' has expected data", async ({ lastMileFailuresPage }) => { + await expect(tableRows(lastMileFailuresPage.page).nth(0).locator("td").nth(0)).toHaveText( + "Tue, 2/20/2024, 9:35 PM", + ); }); - test("table column 'ReportId' will open a modal with report details", async ({ page }) => { - const reportId = tableRows(page).nth(0).locator("td").nth(1); + test("table column 'ReportId' will open a modal with report details", async ({ lastMileFailuresPage }) => { + const reportId = tableRows(lastMileFailuresPage.page).nth(0).locator("td").nth(1); await expect(reportId).toContainText(/e5ce49c0-b230-4364-8230-964273249fa1/); await reportId.click(); - const modal = page.getByTestId("modalWindow").nth(0); + const modal = lastMileFailuresPage.page.getByTestId("modalWindow").nth(0); await expect(modal).toContainText(/Report ID:e5ce49c0-b230-4364-8230-964273249fa1/); }); - test("table column 'Receiver' will open receiver edit page", async ({ page }) => { - const receiver = tableRows(page).nth(0).locator("td").nth(2); + test("table column 'Receiver' will open receiver edit page", async ({ lastMileFailuresPage }) => { + const receiver = tableRows(lastMileFailuresPage.page).nth(0).locator("td").nth(2); await expect(receiver).toContainText(/flexion.etor-service-receiver-results/); await receiver.click(); - await expect(page).toHaveURL( + await expect(lastMileFailuresPage.page).toHaveURL( "/admin/orgreceiversettings/org/flexion/receiver/etor-service-receiver-results/action/edit", ); }); @@ -62,54 +80,36 @@ test.describe("Last Mile Failure page", () => { test.describe("admin user - server error", () => { test.use({ storageState: "e2e/.auth/admin.json" }); - test.beforeEach(async ({ page }) => { - await lastMileFailures.mockGetSendFailuresResponse(page, 500); - await lastMileFailures.goto(page); - }); - - test("has correct title", async ({ page }) => { - await expect(page).toHaveTitle(/Last Mile Failures/); - }); - - test("has alert", async ({ page }) => { - await expect(page.getByTestId("alert")).toBeAttached(); - await expect(page.getByText(/Our apologies, there was an error loading this content./)).toBeAttached(); - }); + test("has alert", async ({ lastMileFailuresPage }) => { + lastMileFailuresPage.mockError = true; + await lastMileFailuresPage.reload(); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + await expect(lastMileFailuresPage.page.getByTestId("alert")).toBeAttached(); + await expect( + lastMileFailuresPage.page.getByText(/Our apologies, there was an error loading this content./), + ).toBeAttached(); }); }); test.describe("receiver user", () => { test.use({ storageState: "e2e/.auth/receiver.json" }); - test.beforeEach(async ({ page }) => { - await lastMileFailures.goto(page); - }); - - test("returns Page Not Found", async ({ page }) => { - await expect(page).toHaveTitle(/Page Not Found/); - }); - - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + test("returns Page Not Found", async ({ lastMileFailuresPage }) => { + await expect(lastMileFailuresPage.page).toHaveTitle(/Page Not Found/); }); }); test.describe("sender user", () => { test.use({ storageState: "e2e/.auth/sender.json" }); - test.beforeEach(async ({ page }) => { - await lastMileFailures.goto(page); - }); - - test("returns Page Not Found", async ({ page }) => { - await expect(page).toHaveTitle(/Page Not Found/); + test("returns Page Not Found", async ({ lastMileFailuresPage }) => { + await expect(lastMileFailuresPage.page).toHaveTitle(/Page Not Found/); }); + }); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ lastMileFailuresPage }) => { + await lastMileFailuresPage.testFooter(); }); }); }); From 632c945e4d79f91c8c14d4278711e6c780b38d69 Mon Sep 17 00:00:00 2001 From: etanb Date: Fri, 23 Aug 2024 16:52:12 -0700 Subject: [PATCH 13/17] POMify message details --- .../pages/authenticated/message-details.ts | 38 ++++- .../message-details-page.spec.ts | 151 ++++++++++-------- 2 files changed, 115 insertions(+), 74 deletions(-) diff --git a/frontend-react/e2e/pages/authenticated/message-details.ts b/frontend-react/e2e/pages/authenticated/message-details.ts index ba57fadeba3..18bf352ab0a 100644 --- a/frontend-react/e2e/pages/authenticated/message-details.ts +++ b/frontend-react/e2e/pages/authenticated/message-details.ts @@ -1,11 +1,35 @@ -import { Page } from "@playwright/test"; - +import { MOCK_GET_MESSAGE } from "../../mocks/messages"; import { MESSAGE_ID } from "../../pages/authenticated/message-id-search"; +import * as messageIdSearch from "../../pages/authenticated/message-id-search"; + +import { BasePage, BasePageTestArgs, RouteHandlerFulfillEntry } from "../BasePage"; + +export class MessageDetailsPage extends BasePage { + static readonly URL_MESSAGE_DETAILS = `/message-details/${MESSAGE_ID}`; + + constructor(testArgs: BasePageTestArgs) { + super( + { + url: MessageDetailsPage.URL_MESSAGE_DETAILS, + title: "ReportStream - CDC's free, interoperable data transfer platform", + heading: testArgs.page.getByRole("heading", { + name: "Message ID Search", + }), + }, + testArgs, + ); -export const URL_MESSAGE_DETAILS = `/message-details/${MESSAGE_ID}`; + this.addMockRouteHandlers([this.createMessageIDSearchAPIHandler()]); + } -export async function goto(page: Page) { - await page.goto(URL_MESSAGE_DETAILS, { - waitUntil: "domcontentloaded", - }); + createMessageIDSearchAPIHandler(): RouteHandlerFulfillEntry { + return [ + messageIdSearch.API_MESSAGE, + () => { + return { + json: MOCK_GET_MESSAGE, + }; + }, + ]; + } } diff --git a/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts index 7378982632d..0f3f9ab0253 100644 --- a/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts @@ -1,71 +1,92 @@ -import { expect, test } from "@playwright/test"; import fs from "node:fs"; import { parseFileLocation } from "../../../../src/utils/misc"; import { tableRows } from "../../../helpers/utils"; import { MOCK_GET_MESSAGE } from "../../../mocks/messages"; -import * as messageDetails from "../../../pages/authenticated/message-details"; -import { URL_MESSAGE_DETAILS } from "../../../pages/authenticated/message-details"; -import * as messageIdSearch from "../../../pages/authenticated/message-id-search"; +import { MessageDetailsPage } from "../../../pages/authenticated/message-details"; import { MESSAGE_ID } from "../../../pages/authenticated/message-id-search"; import { mockGetHistoryReportResponse } from "../../../pages/authenticated/report-details"; + +import { test as baseTest, expect } from "../../../test"; + +export interface MessageDetailsPageFixtures { + messageDetailsPage: MessageDetailsPage; +} + +const test = baseTest.extend({ + messageDetailsPage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + frontendWarningsLogPath, + isFrontendWarningsLog, + }, + use, + ) => { + const page = new MessageDetailsPage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + frontendWarningsLogPath, + isFrontendWarningsLog, + }); + await page.goto(); + await use(page); + }, +}); + test.describe("Message Details Page", () => { test.describe("not authenticated", () => { - test("redirects to login", async ({ page }) => { - await messageDetails.goto(page); - await expect(page).toHaveURL("/login"); + test("redirects to login", async ({ messageDetailsPage }) => { + await expect(messageDetailsPage.page).toHaveURL("/login"); }); }); test.describe("authenticated admin", () => { test.use({ storageState: "e2e/.auth/admin.json" }); - test.beforeEach(async ({ page }) => { - await page.route(messageIdSearch.API_MESSAGE, (route) => - route.fulfill({ - status: 200, - json: MOCK_GET_MESSAGE, - }), - ); - await messageDetails.goto(page); - }); - - test("has correct title", async ({ page }) => { - await expect(page).toHaveURL(URL_MESSAGE_DETAILS); - await expect(page).toHaveTitle(/ReportStream - CDC's free, interoperable data transfer platform/); + test.describe("Header", () => { + test("has correct title + heading", async ({ messageDetailsPage }) => { + await messageDetailsPage.testHeader(); + }); }); - test("has message id section", async ({ page }) => { - await expect(page.getByText("Message ID", { exact: true })).toBeVisible(); - await expect(page.getByText(MESSAGE_ID)).toBeVisible(); + test("has message id section", async ({ messageDetailsPage }) => { + await expect(messageDetailsPage.page.getByText("Message ID", { exact: true })).toBeVisible(); + await expect(messageDetailsPage.page.getByText(MESSAGE_ID)).toBeVisible(); }); - test("has sender section", async ({ page }) => { + test("has sender section", async ({ messageDetailsPage }) => { const { sender, reportId, submittedDate } = MOCK_GET_MESSAGE; - await expect(page.getByText("Sender:")).toBeVisible(); - await expect(page.getByText(sender)).toBeVisible(); - await expect(page.getByText("Incoming Report ID")).toBeVisible(); - await expect(page.getByText(reportId, { exact: true })).toBeVisible(); - await expect(page.getByText("Date/Time Submitted")).toBeVisible(); - await expect(page.getByText(new Date(submittedDate).toLocaleString())).toBeVisible(); - await expect(page.getByText("File Location")).toBeVisible(); - await expect(page.getByText("RECEIVE", { exact: true })).toBeVisible(); - await expect(page.getByText("ignore.ignore-simple-report")).toBeVisible(); - await expect(page.getByText("Incoming File Name")).toBeVisible(); + await expect(messageDetailsPage.page.getByText("Sender:")).toBeVisible(); + await expect(messageDetailsPage.page.getByText(sender)).toBeVisible(); + await expect(messageDetailsPage.page.getByText("Incoming Report ID")).toBeVisible(); + await expect(messageDetailsPage.page.getByText(reportId, { exact: true })).toBeVisible(); + await expect(messageDetailsPage.page.getByText("Date/Time Submitted")).toBeVisible(); + await expect(messageDetailsPage.page.getByText(new Date(submittedDate).toLocaleString())).toBeVisible(); + await expect(messageDetailsPage.page.getByText("File Location")).toBeVisible(); + await expect(messageDetailsPage.page.getByText("RECEIVE", { exact: true })).toBeVisible(); + await expect(messageDetailsPage.page.getByText("ignore.ignore-simple-report")).toBeVisible(); + await expect(messageDetailsPage.page.getByText("Incoming File Name")).toBeVisible(); await expect( - page.getByText("pdi-covid-19-d9a57df0-2702-4e28-9d80-ff8c9ec51816-20240514142655.csv"), + messageDetailsPage.page.getByText( + "pdi-covid-19-d9a57df0-2702-4e28-9d80-ff8c9ec51816-20240514142655.csv", + ), ).toBeVisible(); }); test.describe("authenticated admin", () => { - test("has receiver title", async ({ page }) => { - await expect(page.getByText("Receivers:")).toBeVisible(); - }); - - test("displays expected table headers and data", async ({ page }) => { + test("displays expected table headers and data", async ({ messageDetailsPage }) => { // include header row const rowCount = MOCK_GET_MESSAGE.receiverData.length + 1; - const table = page.getByRole("table"); + const table = messageDetailsPage.page.getByRole("table"); await expect(table).toBeVisible(); const rows = await table.getByRole("row").all(); expect(rows).toHaveLength(rowCount); @@ -112,11 +133,11 @@ test.describe("Message Details Page", () => { } }); - test("table column 'FileName' will download file", async ({ page }) => { - const downloadProm = page.waitForEvent("download"); - await mockGetHistoryReportResponse(page, "*"); + test("table column 'FileName' will download file", async ({ messageDetailsPage }) => { + const downloadProm = messageDetailsPage.page.waitForEvent("download"); + await mockGetHistoryReportResponse(messageDetailsPage.page, "*"); - await tableRows(page).nth(0).locator("td").nth(6).getByRole("button").click(); + await tableRows(messageDetailsPage.page).nth(0).locator("td").nth(6).getByRole("button").click(); const download = await downloadProm; @@ -129,42 +150,38 @@ test.describe("Message Details Page", () => { }); }); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ messageDetailsPage }) => { + await messageDetailsPage.testFooter(); + }); }); }); test.describe("receiver user", () => { test.use({ storageState: "e2e/.auth/receiver.json" }); - test.beforeEach(async ({ page }) => { - await messageDetails.goto(page); - }); + test("has alert", async ({ messageDetailsPage }) => { + messageDetailsPage.mockError = true; + await messageDetailsPage.reload(); - test("has alert", async ({ page }) => { - await expect(page.getByTestId("alert")).toBeAttached(); - await expect(page.getByText(/Our apologies, there was an error loading this content./)).toBeAttached(); - }); - - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + await expect(messageDetailsPage.page.getByTestId("alert")).toBeAttached(); + await expect( + messageDetailsPage.page.getByText(/Our apologies, there was an error loading this content./), + ).toBeAttached(); }); }); test.describe("sender user", () => { test.use({ storageState: "e2e/.auth/sender.json" }); - test.beforeEach(async ({ page }) => { - await messageDetails.goto(page); - }); - - test("has alert", async ({ page }) => { - await expect(page.getByTestId("alert")).toBeAttached(); - await expect(page.getByText(/Our apologies, there was an error loading this content./)).toBeAttached(); - }); + test("has alert", async ({ messageDetailsPage }) => { + messageDetailsPage.mockError = true; + await messageDetailsPage.reload(); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + await expect(messageDetailsPage.page.getByTestId("alert")).toBeAttached(); + await expect( + messageDetailsPage.page.getByText(/Our apologies, there was an error loading this content./), + ).toBeAttached(); }); }); }); From 958c4db9f6508d7e4f70d43470cd03a2f20ad88c Mon Sep 17 00:00:00 2001 From: etanb Date: Mon, 26 Aug 2024 12:09:20 -0700 Subject: [PATCH 14/17] POMify message id search --- .../pages/authenticated/message-details.ts | 7 +- .../pages/authenticated/message-id-search.ts | 51 +++++- .../message-details-page.spec.ts | 4 +- .../message-id-search-page.spec.ts | 158 +++++++++--------- 4 files changed, 128 insertions(+), 92 deletions(-) diff --git a/frontend-react/e2e/pages/authenticated/message-details.ts b/frontend-react/e2e/pages/authenticated/message-details.ts index 18bf352ab0a..124831a1829 100644 --- a/frontend-react/e2e/pages/authenticated/message-details.ts +++ b/frontend-react/e2e/pages/authenticated/message-details.ts @@ -1,11 +1,10 @@ +import { MessageIDSearchPage } from "./message-id-search"; import { MOCK_GET_MESSAGE } from "../../mocks/messages"; -import { MESSAGE_ID } from "../../pages/authenticated/message-id-search"; -import * as messageIdSearch from "../../pages/authenticated/message-id-search"; import { BasePage, BasePageTestArgs, RouteHandlerFulfillEntry } from "../BasePage"; export class MessageDetailsPage extends BasePage { - static readonly URL_MESSAGE_DETAILS = `/message-details/${MESSAGE_ID}`; + static readonly URL_MESSAGE_DETAILS = `/message-details/${MessageIDSearchPage.MESSAGE_ID}`; constructor(testArgs: BasePageTestArgs) { super( @@ -24,7 +23,7 @@ export class MessageDetailsPage extends BasePage { createMessageIDSearchAPIHandler(): RouteHandlerFulfillEntry { return [ - messageIdSearch.API_MESSAGE, + MessageIDSearchPage.API_MESSAGE, () => { return { json: MOCK_GET_MESSAGE, diff --git a/frontend-react/e2e/pages/authenticated/message-id-search.ts b/frontend-react/e2e/pages/authenticated/message-id-search.ts index a71a877b395..d708f3f10c3 100644 --- a/frontend-react/e2e/pages/authenticated/message-id-search.ts +++ b/frontend-react/e2e/pages/authenticated/message-id-search.ts @@ -1,13 +1,46 @@ -import { Page } from "@playwright/test"; +import { MOCK_GET_MESSAGE, MOCK_GET_MESSAGES } from "../../mocks/messages"; +import { BasePage, BasePageTestArgs, RouteHandlerFulfillEntry } from "../BasePage"; -export const URL_MESSAGE_ID_SEARCH = "/admin/message-tracker"; -export const API_MESSAGES = "**/api/messages?messageId=*"; -export const API_MESSAGE = "**/api/message/*"; +export class MessageIDSearchPage extends BasePage { + static readonly URL_MESSAGE_ID_SEARCH = "/admin/message-tracker"; + static readonly API_MESSAGES = "**/api/messages?messageId=*"; + static readonly API_MESSAGE = "**/api/message/*"; + static readonly MESSAGE_ID = "582098"; -export const MESSAGE_ID = "582098"; + constructor(testArgs: BasePageTestArgs) { + super( + { + url: MessageIDSearchPage.URL_MESSAGE_ID_SEARCH, + title: "Message ID search - Admin", + heading: testArgs.page.getByRole("heading", { + name: "Message ID Search", + }), + }, + testArgs, + ); -export async function goto(page: Page) { - await page.goto(URL_MESSAGE_ID_SEARCH, { - waitUntil: "domcontentloaded", - }); + this.addMockRouteHandlers([this.createMessageIDSearchAPIHandler(), this.createMessagesIDSearchAPIHandler()]); + } + + createMessageIDSearchAPIHandler(): RouteHandlerFulfillEntry { + return [ + MessageIDSearchPage.API_MESSAGE, + () => { + return { + json: MOCK_GET_MESSAGE, + }; + }, + ]; + } + + createMessagesIDSearchAPIHandler(): RouteHandlerFulfillEntry { + return [ + MessageIDSearchPage.API_MESSAGES, + () => { + return { + json: MOCK_GET_MESSAGES, + }; + }, + ]; + } } diff --git a/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts index 0f3f9ab0253..916b14b1096 100644 --- a/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-details-page.spec.ts @@ -3,7 +3,7 @@ import { parseFileLocation } from "../../../../src/utils/misc"; import { tableRows } from "../../../helpers/utils"; import { MOCK_GET_MESSAGE } from "../../../mocks/messages"; import { MessageDetailsPage } from "../../../pages/authenticated/message-details"; -import { MESSAGE_ID } from "../../../pages/authenticated/message-id-search"; +import { MessageIDSearchPage } from "../../../pages/authenticated/message-id-search"; import { mockGetHistoryReportResponse } from "../../../pages/authenticated/report-details"; import { test as baseTest, expect } from "../../../test"; @@ -59,7 +59,7 @@ test.describe("Message Details Page", () => { test("has message id section", async ({ messageDetailsPage }) => { await expect(messageDetailsPage.page.getByText("Message ID", { exact: true })).toBeVisible(); - await expect(messageDetailsPage.page.getByText(MESSAGE_ID)).toBeVisible(); + await expect(messageDetailsPage.page.getByText(MessageIDSearchPage.MESSAGE_ID)).toBeVisible(); }); test("has sender section", async ({ messageDetailsPage }) => { diff --git a/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts index 5906ff8929e..9de8e807739 100644 --- a/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/message-id-search-page.spec.ts @@ -1,60 +1,72 @@ -import { expect, test } from "@playwright/test"; import { noData, tableRows } from "../../../helpers/utils"; -import { MOCK_GET_MESSAGE, MOCK_GET_MESSAGES } from "../../../mocks/messages"; -import * as messageIdSearch from "../../../pages/authenticated/message-id-search"; -import { MESSAGE_ID, URL_MESSAGE_ID_SEARCH } from "../../../pages/authenticated/message-id-search"; +import { MOCK_GET_MESSAGES } from "../../../mocks/messages"; +import { MessageIDSearchPage } from "../../../pages/authenticated/message-id-search"; import { openReportIdDetailPage } from "../../../pages/authenticated/submission-history"; -import * as submissionHistory from "../../../pages/authenticated/submission-history"; + +import { test as baseTest, expect } from "../../../test"; + +export interface MessageIDSearchPageFixtures { + messageIDSearchPage: MessageIDSearchPage; +} + +const test = baseTest.extend({ + messageIDSearchPage: async ( + { + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + frontendWarningsLogPath, + isFrontendWarningsLog, + }, + use, + ) => { + const page = new MessageIDSearchPage({ + page: _page, + isMockDisabled, + adminLogin, + senderLogin, + receiverLogin, + storageState, + frontendWarningsLogPath, + isFrontendWarningsLog, + }); + await page.goto(); + await use(page); + }, +}); test.describe("Message ID Search Page", () => { test.describe("not authenticated", () => { - test("redirects to login", async ({ page }) => { - await messageIdSearch.goto(page); - await expect(page).toHaveURL("/login"); + test("redirects to login", async ({ messageIDSearchPage }) => { + await expect(messageIDSearchPage.page).toHaveURL("/login"); }); }); test.describe("authenticated admin", () => { test.use({ storageState: "e2e/.auth/admin.json" }); + test.beforeEach(async ({ messageIDSearchPage }) => { + await messageIDSearchPage.page.locator("#search-field").fill(MessageIDSearchPage.MESSAGE_ID); + await messageIDSearchPage.page + .getByRole("button", { + name: "Search", + }) + .click(); + }); test.describe("on search with results", () => { - test.beforeEach(async ({ page }) => { - await page.route(messageIdSearch.API_MESSAGES, (route) => - route.fulfill({ - status: 200, - json: MOCK_GET_MESSAGES, - }), - ); - await page.route(messageIdSearch.API_MESSAGE, (route) => - route.fulfill({ - status: 200, - json: MOCK_GET_MESSAGE, - }), - ); - await submissionHistory.mockGetReportHistoryResponse(page); - await messageIdSearch.goto(page); - - await page.locator("#search-field").fill(MESSAGE_ID); - await page - .getByRole("button", { - name: "Search", - }) - .click(); - }); - - test("has correct title", async ({ page }) => { - await expect(page).toHaveURL(URL_MESSAGE_ID_SEARCH); - await expect(page).toHaveTitle(/Message ID search - Admin/); - }); - - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + test.describe("Header", () => { + test("has correct title + heading", async ({ messageIDSearchPage }) => { + await messageIDSearchPage.testHeader(); + }); }); - test("displays expected table headers and data", async ({ page }) => { + test("displays expected table headers and data", async ({ messageIDSearchPage }) => { // include header row const rowCount = MOCK_GET_MESSAGES.length + 1; - const table = page.getByRole("table"); + const table = messageIDSearchPage.page.getByRole("table"); await expect(table).toBeVisible(); const rows = await table.getByRole("row").all(); expect(rows).toHaveLength(rowCount); @@ -85,39 +97,39 @@ test.describe("Message ID Search Page", () => { } }); - test("table column 'Message ID' will open message id details", async ({ page }) => { - const messageIdCell = tableRows(page) + test("table column 'Message ID' will open message id details", async ({ messageIDSearchPage }) => { + const messageIdCell = tableRows(messageIDSearchPage.page) .nth(0) .locator("td") .nth(0) - .getByRole("link", { name: MESSAGE_ID }); + .getByRole("link", { name: MessageIDSearchPage.MESSAGE_ID }); await messageIdCell.click(); - await expect(page).toHaveURL("/message-details/0"); - expect(page.locator("h1").getByText(MESSAGE_ID)).toBeTruthy(); + await expect(messageIDSearchPage.page).toHaveURL("/message-details/0"); + expect(messageIDSearchPage.page.locator("h1").getByText(MessageIDSearchPage.MESSAGE_ID)).toBeTruthy(); }); - test("table column 'Incoming Report Id' will open report id details", async ({ page }) => { + test("table column 'Incoming Report Id' will open report id details", async ({ messageIDSearchPage }) => { const reportId = "73e3cbc8-9920-4ab7-871f-843a1db4c074"; - const reportIdCell = tableRows(page).nth(0).locator("td").nth(3).getByRole("link", { + const reportIdCell = tableRows(messageIDSearchPage.page).nth(0).locator("td").nth(3).getByRole("link", { name: reportId, }); await reportIdCell.click(); - await openReportIdDetailPage(page, reportId); + await openReportIdDetailPage(messageIDSearchPage.page, reportId); }); }); test.describe("on search without results", () => { - test.beforeEach(async ({ page }) => { - await page.route(messageIdSearch.API_MESSAGES, (route) => + test.beforeEach(async ({ messageIDSearchPage }) => { + await messageIDSearchPage.page.route(MessageIDSearchPage.API_MESSAGES, (route) => route.fulfill({ status: 200, json: [], }), ); - await messageIdSearch.goto(page); + await messageIDSearchPage.page.goto(MessageIDSearchPage.URL_MESSAGE_ID_SEARCH); - await page.locator("#search-field").fill(MESSAGE_ID); - await page + await messageIDSearchPage.page.locator("#search-field").fill(MessageIDSearchPage.MESSAGE_ID); + await messageIDSearchPage.page .getByRole("button", { name: "Search", }) @@ -125,49 +137,41 @@ test.describe("Message ID Search Page", () => { }); test("has correct title", async ({ page }) => { - await expect(page).toHaveURL(URL_MESSAGE_ID_SEARCH); + await expect(page).toHaveURL(MessageIDSearchPage.URL_MESSAGE_ID_SEARCH); await expect(page).toHaveTitle(/Message ID search - Admin/); }); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); - }); - test("shows no data", async ({ page }) => { await expect(noData(page)).toBeAttached(); }); }); + + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ messageIDSearchPage }) => { + await messageIDSearchPage.testFooter(); + }); + }); }); test.describe("receiver user", () => { test.use({ storageState: "e2e/.auth/receiver.json" }); - test.beforeEach(async ({ page }) => { - await messageIdSearch.goto(page); - }); - - test("returns Page Not Found", async ({ page }) => { - await expect(page).toHaveTitle(/Page Not Found/); - }); + test("has alert", async ({ messageIDSearchPage }) => { + messageIDSearchPage.mockError = true; + await messageIDSearchPage.reload(); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + await expect(messageIDSearchPage.page).toHaveTitle(/Page Not Found/); }); }); test.describe("sender user", () => { test.use({ storageState: "e2e/.auth/sender.json" }); - test.beforeEach(async ({ page }) => { - await messageIdSearch.goto(page); - }); - - test("returns Page Not Found", async ({ page }) => { - await expect(page).toHaveTitle(/Page Not Found/); - }); + test("has alert", async ({ messageIDSearchPage }) => { + messageIDSearchPage.mockError = true; + await messageIDSearchPage.reload(); - test("has footer", async ({ page }) => { - await expect(page.locator("footer")).toBeAttached(); + await expect(messageIDSearchPage.page).toHaveTitle(/Page Not Found/); }); }); }); From 7381f61c23ab81d7efc9b36d896aa0be4622aca7 Mon Sep 17 00:00:00 2001 From: etanb Date: Mon, 26 Aug 2024 13:07:58 -0700 Subject: [PATCH 15/17] DRY everything --- .../admin/receiver-status-page.spec.ts | 33 +++++++++++-------- .../organization-settings-page.spec.ts | 12 +++++++ .../getting-started/receiving-data.spec.ts | 7 ++-- .../getting-started/sending-data.spec.ts | 7 ++-- .../managing-your-connection-page.spec.ts | 7 ++-- .../refer-healthcare-page.spec.ts | 7 ++-- .../e2e/spec/all/public/support-page.spec.ts | 7 ++-- 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts index cbe14099d98..f8f92d2615b 100644 --- a/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/admin/receiver-status-page.spec.ts @@ -71,23 +71,20 @@ test.describe("Admin Receiver Status Page", () => { await expect(adminReceiverStatusPage.page.getByText("there was an error")).toBeVisible(); }); - test( - "Has correct title", - { - tag: "@smoke", - }, - async ({ adminReceiverStatusPage }) => { - await expect(adminReceiverStatusPage.page).toHaveURL(adminReceiverStatusPage.url); - await expect(adminReceiverStatusPage.page).toHaveTitle(adminReceiverStatusPage.title); - }, - ); + test.describe("Header", () => { + test( + "has correct title + heading", + { + tag: "@smoke", + }, + async ({ adminReceiverStatusPage }) => { + await adminReceiverStatusPage.testHeader(); + }, + ); + }); test.describe("When there is no error", () => { test.describe("Displays correctly", () => { - test("header", async ({ adminReceiverStatusPage }) => { - await expect(adminReceiverStatusPage.heading).toBeVisible(); - }); - test.describe( "filters", { @@ -153,6 +150,14 @@ test.describe("Admin Receiver Status Page", () => { }); }); + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ + adminReceiverStatusPage, + }) => { + await adminReceiverStatusPage.testFooter(); + }); + }); + test.describe("Functions correctly", () => { test.describe("filters", () => { test.describe( diff --git a/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts index d2aecc8499c..bd9d3eefb2e 100644 --- a/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts @@ -42,6 +42,18 @@ const test = baseTest.extend({ }); test.describe("Admin Organization Settings Page", () => { + test.describe("Header", () => { + test("has correct title + heading", async ({ organizationPage }) => { + await organizationPage.testHeader(); + }); + }); + + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ organizationPage }) => { + await organizationPage.testFooter(); + }); + }); + test.describe("not authenticated", () => { test("redirects to login", async ({ organizationPage }) => { await expect(organizationPage.page).toHaveURL("/login"); diff --git a/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts index ebe69ae059c..0a7755d0c4f 100644 --- a/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/receiving-data.spec.ts @@ -36,9 +36,10 @@ const test = baseTest.extend({ }); test.describe("Receiving data page", () => { - test("has correct title", async ({ receivingDataPage }) => { - await expect(receivingDataPage.page).toHaveTitle(receivingDataPage.title); - await expect(receivingDataPage.heading).toBeVisible(); + test.describe("Header", () => { + test("has correct title + heading", async ({ receivingDataPage }) => { + await receivingDataPage.testHeader(); + }); }); test("has link to onboarding form", async ({ receivingDataPage }) => { diff --git a/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts index 3d6a87b7289..fc915c2c7cd 100644 --- a/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts +++ b/frontend-react/e2e/spec/all/public/getting-started/sending-data.spec.ts @@ -36,9 +36,10 @@ const test = baseTest.extend({ }); test.describe("Sending data page", () => { - test("has correct title", async ({ sendingDataPage }) => { - await expect(sendingDataPage.page).toHaveTitle(sendingDataPage.title); - await expect(sendingDataPage.heading).toBeVisible(); + test.describe("Header", () => { + test("has correct title + heading", async ({ sendingDataPage }) => { + await sendingDataPage.testHeader(); + }); }); test("has link to get started with ReportStream", async ({ sendingDataPage }) => { diff --git a/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts index 832c88107ce..e10692aa357 100644 --- a/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/managing-your-connection-page.spec.ts @@ -51,9 +51,10 @@ test.describe( tag: "@smoke", }, () => { - test("has correct title", async ({ managingYourConnectionPage }) => { - await expect(managingYourConnectionPage.page).toHaveTitle(managingYourConnectionPage.title); - await expect(managingYourConnectionPage.heading).toBeVisible(); + test.describe("Header", () => { + test("has correct title + heading", async ({ managingYourConnectionPage }) => { + await managingYourConnectionPage.testHeader(); + }); }); test.describe("Quick links", () => { diff --git a/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts index 473570986d9..27c3c74899c 100644 --- a/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/managing-your-connection/refer-healthcare-page.spec.ts @@ -40,9 +40,10 @@ test.describe( tag: "@smoke", }, () => { - test("has correct title", async ({ referHealthcarePage }) => { - await expect(referHealthcarePage.page).toHaveTitle(referHealthcarePage.title); - await expect(referHealthcarePage.heading).toBeVisible(); + test.describe("Header", () => { + test("has correct title + heading", async ({ referHealthcarePage }) => { + await referHealthcarePage.testHeader(); + }); }); test("has correct sidenav items", async ({ referHealthcarePage }) => { diff --git a/frontend-react/e2e/spec/all/public/support-page.spec.ts b/frontend-react/e2e/spec/all/public/support-page.spec.ts index d466132a43e..fc18518233f 100644 --- a/frontend-react/e2e/spec/all/public/support-page.spec.ts +++ b/frontend-react/e2e/spec/all/public/support-page.spec.ts @@ -51,9 +51,10 @@ const test = baseTest.extend({ }); test.describe("Support page", () => { - test("has correct title", async ({ supportPage }) => { - await expect(supportPage.page).toHaveTitle(supportPage.title); - await expect(supportPage.heading).toBeVisible(); + test.describe("Header", () => { + test("has correct title + heading", async ({ supportPage }) => { + await supportPage.testHeader(); + }); }); test("Should have a way of contacting support", async ({ supportPage }) => { From cce8b7e83792f4f552d54b2170ebcf46fb271d1d Mon Sep 17 00:00:00 2001 From: etanb Date: Mon, 26 Aug 2024 13:24:35 -0700 Subject: [PATCH 16/17] fix org tests --- .../e2e/pages/authenticated/organization.ts | 2 +- .../organization-settings-page.spec.ts | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontend-react/e2e/pages/authenticated/organization.ts b/frontend-react/e2e/pages/authenticated/organization.ts index 413e69fe734..6d24305989d 100644 --- a/frontend-react/e2e/pages/authenticated/organization.ts +++ b/frontend-react/e2e/pages/authenticated/organization.ts @@ -9,7 +9,7 @@ export class OrganizationPage extends BasePage { super( { url: "/admin/settings", - title: "Organizations", + title: "Admin-Organizations", heading: testArgs.page.getByRole("heading", { name: "Organizations", }), diff --git a/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts index bd9d3eefb2e..83ce97b9e2a 100644 --- a/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts +++ b/frontend-react/e2e/spec/all/authenticated/organization-settings-page.spec.ts @@ -42,18 +42,6 @@ const test = baseTest.extend({ }); test.describe("Admin Organization Settings Page", () => { - test.describe("Header", () => { - test("has correct title + heading", async ({ organizationPage }) => { - await organizationPage.testHeader(); - }); - }); - - test.describe("Footer", () => { - test("has footer and explicit scroll to footer and scroll to top", async ({ organizationPage }) => { - await organizationPage.testFooter(); - }); - }); - test.describe("not authenticated", () => { test("redirects to login", async ({ organizationPage }) => { await expect(organizationPage.page).toHaveURL("/login"); @@ -77,6 +65,12 @@ test.describe("Admin Organization Settings Page", () => { test.describe("authenticated admin", () => { test.use({ storageState: "e2e/.auth/admin.json" }); + test.describe("Header", () => { + test("has correct title + heading", async ({ organizationPage }) => { + await organizationPage.testHeader(); + }); + }); + test("If there is an error, the error is shown on the page", async ({ organizationPage }) => { organizationPage.mockError = true; await organizationPage.reload(); @@ -241,4 +235,10 @@ test.describe("Admin Organization Settings Page", () => { }); }); }); + + test.describe("Footer", () => { + test("has footer and explicit scroll to footer and scroll to top", async ({ organizationPage }) => { + await organizationPage.testFooter(); + }); + }); }); From 1c38d2b7952ab10f9808173304cd2dd2a6d703cb Mon Sep 17 00:00:00 2001 From: etanb Date: Mon, 26 Aug 2024 15:22:55 -0700 Subject: [PATCH 17/17] fix path issue --- frontend-react/e2e/spec/all/daily-data-page-user-flow.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend-react/e2e/spec/all/daily-data-page-user-flow.spec.ts b/frontend-react/e2e/spec/all/daily-data-page-user-flow.spec.ts index 03156ebc07f..71aaa857b75 100644 --- a/frontend-react/e2e/spec/all/daily-data-page-user-flow.spec.ts +++ b/frontend-react/e2e/spec/all/daily-data-page-user-flow.spec.ts @@ -28,8 +28,8 @@ import { setTime, startDate, startTime, -} from "../../pages/daily-data"; -import { URL_REPORT_DETAILS } from "../../pages/report-details"; +} 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";