Skip to content

Commit

Permalink
Merge pull request #4613 from mozilla/mntor-3140
Browse files Browse the repository at this point in the history
  • Loading branch information
mozilloid authored Aug 1, 2024
2 parents 7b08bd4 + 61f7986 commit 62ec4eb
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 47 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/e2e_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ jobs:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/blurts
HIBP_KANON_API_TOKEN: ${{ secrets.HIBP_KANON_API_TOKEN }}
HIBP_API_TOKEN: ${{ secrets.HIBP_API_TOKEN }}
HIBP_KANON_API_ROOT: "http://localhost:6060/api/mock/hibp"
ONEREP_API_BASE: "http://localhost:6060/api/mock/onerep/"
# Our tests are currently set up to expect accounts to act like
# old user accounts, so let's pretend they all are:
BROKER_SCAN_RELEASE_DATE: "3000-12-31"
Expand Down
3 changes: 3 additions & 0 deletions src/e2e/pages/dashBoardPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export class DashboardPage {
readonly overviewCard: Locator;
readonly overviewCardSummary: Locator;
readonly overviewCardFindings: Locator;
readonly chartSvgExposuresCount: Locator;

readonly upsellScreenButton: Locator;
readonly urlRegex: RegExp;
Expand Down Expand Up @@ -251,6 +252,8 @@ export class DashboardPage {
this.overviewCardFindings = page.locator(
"[aria-label='Dashboard summary'] > div > h3",
);
this.chartSvgExposuresCount =
this.overviewCard.locator("figure > div > svg");

//regex
this.urlRegex = /\/dashboard\/(fixed|action-needed)\/?/;
Expand Down
208 changes: 162 additions & 46 deletions src/e2e/specs/dashboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ import {
clickOnATagCheckDomain,
escapeRegExp,
forceLoginAs,
resetTestData,
} from "../utils/helpers.js";
import {
isUsingMockHIBPEndpoint,
isUsingMockONEREPEndpoint,
} from "../../app/functions/universal/mock.js";

// bypass login
test.use({ storageState: "./e2e/storageState.json" });
test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Headers`, () => {
test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Headers @smoke`, () => {
test.beforeEach(async ({ dashboardPage, page }) => {
await dashboardPage.open();

Expand Down Expand Up @@ -256,7 +261,7 @@ test.describe.skip(
},
);

test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Content`, () => {
test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Content @smoke`, () => {
test.beforeEach(async ({ dashboardPage, page }) => {
await dashboardPage.open();

Expand Down Expand Up @@ -336,7 +341,7 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Content`, () =
});
});

test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Payment`, () => {
test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Payment`, () => {
test.beforeEach(async ({ dashboardPage, page }) => {
await dashboardPage.open();

Expand Down Expand Up @@ -669,7 +674,7 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Footer`, () =>
});
});

test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Navigation`, () => {
test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Navigation @smoke`, () => {
test.beforeEach(async ({ dashboardPage, page }) => {
await dashboardPage.open();

Expand Down Expand Up @@ -720,49 +725,160 @@ test.describe(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Navigation`, (
});
});

// This test has inconsistent results - may need to rely on mocks.
test.describe.skip(
`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Data Breaches`,
() => {
test.beforeEach(async ({ landingPage, page, authPage }) => {
const emailToUse = process.env
.E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED as string;
const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD as string;
expect(emailToUse).not.toBeUndefined();
expect(pwdToUse).not.toBeUndefined();
await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
// These tests rely heavily on mocks
test.skip(`${process.env.E2E_TEST_ENV} - Breaches Dashboard - Data Breaches`, () => {
test.use({ storageState: { cookies: [], origins: [] } });

test("Verify that the High risk data breaches step is displayed correctly", async ({
dashboardPage,
dataBrokersPage,
page,
landingPage,
authPage,
}) => {
if (!isUsingMockHIBPEndpoint() || !isUsingMockONEREPEndpoint()) return;
const emailToUse = process.env.E2E_TEST_ACCOUNT_EMAIL_EXPOSURES_STARTED!;
const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD!;
expect(emailToUse).not.toBeUndefined();
expect(pwdToUse).not.toBeUndefined();
await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
await resetTestData(page, true, true);
await dashboardPage.open();

test.info().annotations.push({
type: "testrail",
description:
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463592",
});

test("Verify that the High risk data breaches step is displayed correctly", async ({
dashboardPage,
dataBrokersPage,
page,
}) => {
test.info().annotations.push({
type: "testrail",
description:
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463592",
});
await expect(dashboardPage.upsellScreenButton).toBeVisible();
await dashboardPage.upsellScreenButton.click();
await page.waitForURL(/.*\/data-broker-profiles\/view-data-brokers\/?/);
await expect(dataBrokersPage.forwardArrowButton).toBeVisible();
await dataBrokersPage.forwardArrowButton.click();
await page.waitForURL(/.*\/high-risk-data-breaches.*/);
const highRiskDataBreachLi = page.locator(
'li:has(div:has-text("High risk data breaches"))',
);
await expect(highRiskDataBreachLi).toBeVisible();
await expect(highRiskDataBreachLi).toHaveAttribute("aria-current", "step");
await expect(
highRiskDataBreachLi.locator("div").getByText("High risk data breaches"),
).toBeVisible();
});

await expect(dashboardPage.upsellScreenButton).toBeVisible();
await dashboardPage.upsellScreenButton.click();
await page.waitForURL(/.*\/data-broker-profiles\/view-data-brokers\/?/);
await expect(dataBrokersPage.forwardArrowButton).toBeVisible();
await dataBrokersPage.forwardArrowButton.click();
await page.waitForURL(/.*\/high-risk-data-breaches.*/);
const highRiskDataBreachLi = page.locator(
'li:has(div:has-text("High risk data breaches"))',
);
await expect(highRiskDataBreachLi).toBeVisible();
await expect(highRiskDataBreachLi).toHaveAttribute(
"aria-current",
"step",
);
await expect(
highRiskDataBreachLi
.locator("div")
.getByText("High risk data breaches"),
).toBeVisible();
test("Verify that the dashboard is displayed correctly for users with no scan results and no breaches", async ({
dashboardPage,
page,
authPage,
landingPage,
}) => {
if (!isUsingMockHIBPEndpoint() || !isUsingMockONEREPEndpoint()) return;

test.info().annotations.push({
type: "testrail",
description:
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463610",
});
},
);

const emailToUse =
process.env.E2E_TEST_ACCOUNT_EMAIL_ZERO_BREACHES_ZERO_BROKERS!;
const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD!;
expect(emailToUse).not.toBeUndefined();
expect(pwdToUse).not.toBeUndefined();
await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
await resetTestData(page, true, true);
await dashboardPage.open();

await expect(dashboardPage.overviewCard).toBeVisible();
const textArea = dashboardPage.overviewCard.locator("section");
await expect(textArea.getByText(/No exposures found/)).toBeVisible();
await expect(
textArea.getByText(
/Great news! We searched all known data breaches and .\d+. data broker sites that sell personal info and found no exposures\./,
),
).toBeVisible();
await expect(textArea.getByRole("button")).toBeVisible();
expect(await dashboardPage.overviewCard.locator("svg").count()).toBe(5);
expect(await dashboardPage.overviewCard.locator("circle").count()).toBe(4);
await expect(
dashboardPage.chartSvgExposuresCount.getByText("Exposures"),
).toBeVisible();
await expect(
dashboardPage.chartSvgExposuresCount.getByText("0"),
).toBeVisible();

await expect(dashboardPage.exposuresHeading).toBeVisible();
expect(await dashboardPage.exposuresHeading.textContent()).toBe(
"View all sites where your info is exposed",
);

const noExpFoundMsg = page
.locator("div > strong")
.getByText("No exposures found");
await expect(noExpFoundMsg).toBeVisible();
});

test("Verify that the dashboard is displayed correctly for users with no scan results and with data breaches", async ({
dashboardPage,
page,
authPage,
landingPage,
}) => {
if (!isUsingMockHIBPEndpoint() || !isUsingMockONEREPEndpoint()) return;

test.info().annotations.push({
type: "testrail",
description:
"https://testrail.stage.mozaws.net/index.php?/cases/view/2463611",
});

const emailToUse = process.env.E2E_TEST_ACCOUNT_EMAIL_ZERO_BROKERS!;
const pwdToUse = process.env.E2E_TEST_ACCOUNT_PASSWORD!;
expect(emailToUse).not.toBeUndefined();
expect(pwdToUse).not.toBeUndefined();
await forceLoginAs(emailToUse, pwdToUse, page, landingPage, authPage);
await resetTestData(page, true, true);
await dashboardPage.open();

// Assertions for the overview card
await expect(dashboardPage.overviewCard).toBeVisible();
await expect(
page.getByText(
/You still have .\d+. exposures left to fix. Keep going and protect yourself\. We.ll guide you step-by-step\./,
),
).toBeVisible();
await expect(dashboardPage.upsellScreenButton).toBeVisible();

// Chart reflecting results
await expect(
dashboardPage.chartSvgExposuresCount.getByText("Exposures"),
).toBeVisible();
await expect(
dashboardPage.chartSvgExposuresCount.getByText(/\d+/),
).toBeVisible();

// Text above exposures list
await expect(
page.getByText("View all sites where your info is exposed"),
).toBeVisible();
await expect(
page.getByText(
/We found your information exposed .\d+. times over .\d+. data breaches and .0. data broker sites that are selling your personal info\./,
),
).toBeVisible();

// Exposures list
const exposureList = page.locator('[class*="exposureList"]');
await expect(exposureList).toBeVisible();
expect(await exposureList.locator("li").count()).toBeGreaterThan(0);

// Click the "Let's keep going" button and check the redirection
await dashboardPage.upsellScreenButton.click();
await page.waitForURL(/.*\/user\/dashboard\/fix.*/);
const dataBrokerFixed = page
.locator('[class*="FixNavigation"][class*="isCompleted"]')
.getByText("Data broker profiles");
await expect(dataBrokerFixed).toBeVisible();
});
});
20 changes: 19 additions & 1 deletion src/e2e/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ export const clickOnATagCheckDomain = async (
page: Page,
) => {
if (typeof host === "string")
host = new RegExp(escapeRegExp(host.replace(/^(https?:\/\/)/, "")));
host = new RegExp(
escapeRegExp(host.replace(/^(https?:\/\/)/, "").replace(/:\d+$/, "")),
);
if (typeof path === "string") path = new RegExp(".*" + path + ".*");

const href = await aTag.getAttribute("href");
Expand Down Expand Up @@ -224,3 +226,19 @@ export const forceLoginAs = async (
export async function emailInputShouldExist(landingPage: LandingPage) {
return 0 < (await landingPage.emailInputPrompt.count());
}

export const resetTestData = async (
page: Page,
hibp: boolean,
onerep: boolean,
) => {
const baseUrl = process.env.SERVER_URL!;
const param1 = `${hibp ? "hibp=true" : ""}`;
const param2 = `${onerep ? "onerep=true" : ""}`;
let delim = "";
if (param1 && param2) delim = "&";
const params = param1 + delim + param2;
const completeUrl = baseUrl + "/api/mock/resetTestData?" + params;
const res = await page.request.get(completeUrl);
expect(res.ok()).toBeTruthy();
};

0 comments on commit 62ec4eb

Please sign in to comment.