From c40c9798a96c769d97d5bd1487f7b41617a7ea96 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Thu, 31 Oct 2024 14:39:40 +0000 Subject: [PATCH] initial setup --- .../src/demo-space/demo-login.spec.ts | 74 +++++++++++++++++++ e2e/tests/ui-driven/src/helpers/context.ts | 37 ++++++++++ .../ui-driven/src/helpers/globalHelpers.ts | 29 +++++++- 3 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 e2e/tests/ui-driven/src/demo-space/demo-login.spec.ts diff --git a/e2e/tests/ui-driven/src/demo-space/demo-login.spec.ts b/e2e/tests/ui-driven/src/demo-space/demo-login.spec.ts new file mode 100644 index 0000000000..dbc4333d5e --- /dev/null +++ b/e2e/tests/ui-driven/src/demo-space/demo-login.spec.ts @@ -0,0 +1,74 @@ +import { expect, test } from "@playwright/test"; +import type { Context } from "../helpers/context"; +import { + contextDefaults, + setUpTestContext, + tearDownTestContext, +} from "../helpers/context"; +import { createAuthenticatedSession } from "../helpers/globalHelpers"; + +test.describe("Login", () => { + let context: Context = { + ...contextDefaults, + }; + + test.beforeAll(async () => { + try { + context = await setUpTestContext(context); + } catch (error) { + // ensure proper teardown if setup fails + await tearDownTestContext(context); + throw error; + } + }); + + test.afterAll(async () => { + await tearDownTestContext(context); + }); + + test("setting a cookie bypasses login", async ({ browser }) => { + const page = await createAuthenticatedSession({ + browser, + userId: context.user!.id!, + }); + + await page.goto("/"); + await page.waitForResponse((response) => { + return response.url().includes("/graphql"); + }); + + const team = page.locator("h3", { hasText: context.team.name }); + await expect(team).toBeVisible(); + }); + + test("shows error toast when there is a network error and removes it when a retry is successful", async ({ + browser, + }) => { + const page = await createAuthenticatedSession({ + browser, + userId: context.user!.id!, + }); + await page.goto("/"); + + const teamLink = page.locator("h3").filter({ hasText: context.team.name }); + await teamLink.waitFor(); // wait for this to be visible + + // drop graphql requests + await page.route("**/graphql", (route) => { + route.abort("connectionfailed"); + }); + + await teamLink.click(); + const toastText = "Network error, attempting to reconnect…"; + await expect(page.getByText(toastText)).toBeVisible(); + + // resume graphql requests + await page.route("**/graphql", (route) => { + route.continue(); + }); + await expect( + page.locator("h1").filter({ hasText: "Services" }), + ).toBeVisible(); + await expect(page.getByText(toastText)).toBeHidden(); + }); +}); diff --git a/e2e/tests/ui-driven/src/helpers/context.ts b/e2e/tests/ui-driven/src/helpers/context.ts index c94783189e..9011cf9277 100644 --- a/e2e/tests/ui-driven/src/helpers/context.ts +++ b/e2e/tests/ui-driven/src/helpers/context.ts @@ -46,6 +46,28 @@ export const contextDefaults: Context = { }, }; +export const demoContext: Context = { + user: { + firstName: "Demo", + lastName: "demo", + email: "simulate-delivered@notifications.service.gov.uk", + isPlatformAdmin: false, + }, + team: { + name: "E2E Test Team", + slug: "E2E", + theme: { + logo: "https://raw.githubusercontent.com/theopensystemslab/planx-team-logos/main/planx-testing.svg", + primaryColour: "#444444", + }, + settings: { + homepage: "planx.uk", + submissionEmail: "simulate-delivered@notifications.service.gov.uk", + }, + }, +}; + + export async function setUpTestContext( initialContext: Context, ): Promise { @@ -121,6 +143,21 @@ export function generateAuthenticationToken(userId: string) { ); } +export function generateAuthenticationDemoToken(userId: string) { + assert(process.env.JWT_SECRET); + return sign( + { + sub: `${userId}`, + "https://hasura.io/jwt/claims": { + "x-hasura-allowed-roles": ["public","demoUser"], + "x-hasura-default-role": "demoUser", + "x-hasura-user-id": `${userId}`, + }, + }, + process.env.JWT_SECRET, + ); +} + export function getCoreDomainClient(): CoreDomainClient { assert(process.env.HASURA_GRAPHQL_URL); assert(process.env.HASURA_GRAPHQL_ADMIN_SECRET); diff --git a/e2e/tests/ui-driven/src/helpers/globalHelpers.ts b/e2e/tests/ui-driven/src/helpers/globalHelpers.ts index 29e00f7e64..fb19baaab3 100644 --- a/e2e/tests/ui-driven/src/helpers/globalHelpers.ts +++ b/e2e/tests/ui-driven/src/helpers/globalHelpers.ts @@ -2,7 +2,7 @@ import { FlowGraph } from "@opensystemslab/planx-core/types"; import type { Browser, Page, Request } from "@playwright/test"; import { gql } from "graphql-request"; import type { Context } from "./context"; -import { generateAuthenticationToken, getGraphQLClient } from "./context"; +import { generateAuthenticationDemoToken, generateAuthenticationToken, getGraphQLClient } from "./context"; // Test card numbers to be used in gov.uk sandbox environment // reference: https://docs.payments.service.gov.uk/testing_govuk_pay/#if-you-39-re-using-a-test-39-sandbox-39-account @@ -69,6 +69,33 @@ export async function createAuthenticatedSession({ return page; } +export async function createAuthenticatedDemoSession({ + browser, + userId, +}: { + browser: Browser; + userId: number; +}): Promise { + const browserContext = await browser.newContext(); + const page = await browserContext.newPage(); + const token = generateAuthenticationDemoToken(`${userId}`); + await browserContext.addCookies([ + { + name: "jwt", + domain: "localhost", + path: "/", + value: token, + }, + { + name: "auth", + domain: "localhost", + path: "/", + value: JSON.stringify({ loggedIn: true }), + }, + ]); + return page; +} + export async function setFeatureFlag(page: Page, featureFlag: string) { await page.addInitScript( (featureFlag: string) =>