From eee94eef47fe9380c26e5d5311c68d39b1b67fe0 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Fri, 29 Nov 2024 14:17:38 +0000 Subject: [PATCH] revert flows change and add expect to makePaymentRequest separate out types and service data lint fix --- .../src/create-flow-with-geospatial.spec.ts | 27 ++---- e2e/tests/ui-driven/src/create-flow.spec.ts | 43 ++++----- .../ui-driven/src/helpers/addComponent.ts | 3 +- e2e/tests/ui-driven/src/helpers/context.ts | 90 ++++++------------- .../ui-driven/src/helpers/globalHelpers.ts | 12 +-- .../src/helpers/navigateAndPublish.ts | 2 - .../ui-driven/src/helpers/serviceData.ts | 14 +++ e2e/tests/ui-driven/src/helpers/types.ts | 20 +++++ .../ui-driven/src/helpers/userActions.ts | 10 +-- .../ui-driven/src/invite-to-pay/agent.spec.ts | 20 ++--- .../ui-driven/src/invite-to-pay/helpers.ts | 12 +-- .../src/invite-to-pay/nominee.spec.ts | 33 ++++--- e2e/tests/ui-driven/src/login.spec.ts | 4 +- e2e/tests/ui-driven/src/pages/Editor.ts | 7 ++ e2e/tests/ui-driven/src/pay.spec.ts | 20 ++--- e2e/tests/ui-driven/src/refresh-page.spec.ts | 4 +- .../ui-driven/src/save-and-return.spec.ts | 18 ++-- e2e/tests/ui-driven/src/sections.spec.ts | 24 +++-- 18 files changed, 172 insertions(+), 191 deletions(-) create mode 100644 e2e/tests/ui-driven/src/helpers/serviceData.ts create mode 100644 e2e/tests/ui-driven/src/helpers/types.ts diff --git a/e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts b/e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts index 5a41195bfa..bf88ebeb8b 100644 --- a/e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts +++ b/e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts @@ -1,5 +1,4 @@ import { expect, test } from "@playwright/test"; -import type { Context } from "./helpers/context"; import { contextDefaults, setUpTestContext, @@ -9,15 +8,17 @@ import { getTeamPage } from "./helpers/getPage"; import { createAuthenticatedSession } from "./helpers/globalHelpers"; import { answerFindProperty, clickContinue } from "./helpers/userActions"; import { PlaywrightEditor } from "./pages/Editor"; +import { + publishService, + turnServiceOnline, +} from "./helpers/navigateAndPublish"; +import { TestContext } from "./helpers/types"; +import { serviceProps } from "./helpers/serviceData"; test.describe("Flow creation, publish and preview", () => { - let context: Context = { + let context: TestContext = { ...contextDefaults, }; - const serviceProps = { - name: "A Test Service", - slug: "a-test-service", - }; test.beforeAll(async () => { try { @@ -44,9 +45,6 @@ test.describe("Flow creation, publish and preview", () => { page.on("dialog", (dialog) => dialog.accept(serviceProps.name)); await editor.addNewService(); - // update context to allow flow to be torn down - context.flows = [{ ...serviceProps }]; - await editor.createFindProperty(); await expect(editor.nodeList).toContainText(["Find property"]); await editor.createInternalPortal(); @@ -79,8 +77,7 @@ test.describe("Flow creation, publish and preview", () => { }); // publish flow await page.goto(`/${context.team.slug}/${serviceProps.slug}`); - page.getByRole("button", { name: "CHECK FOR CHANGES TO PUBLISH" }).click(); - page.getByRole("button", { name: "PUBLISH", exact: true }).click(); + publishService(page); let previewLink = page.getByRole("link", { name: "Open published service", @@ -89,13 +86,7 @@ test.describe("Flow creation, publish and preview", () => { await page.goto(`/${context.team.slug}/${serviceProps.slug}`); - // Toggle flow online - page.locator('[aria-label="Service settings"]').click(); - page.getByLabel("Offline").click(); - page.getByRole("button", { name: "Save", disabled: false }).click(); - await expect( - page.getByText("Service settings updated successfully"), - ).toBeVisible(); + turnServiceOnline(page); // Exit back to main Editor page page.locator('[aria-label="Editor"]').click(); diff --git a/e2e/tests/ui-driven/src/create-flow.spec.ts b/e2e/tests/ui-driven/src/create-flow.spec.ts index dab9f9d4db..f233fd9d1d 100644 --- a/e2e/tests/ui-driven/src/create-flow.spec.ts +++ b/e2e/tests/ui-driven/src/create-flow.spec.ts @@ -1,9 +1,6 @@ import { Browser, expect, test } from "@playwright/test"; -import type { Context } from "./helpers/context"; import { contextDefaults, - externalPortalFlowData, - externalPortalServiceProps, setUpTestContext, tearDownTestContext, } from "./helpers/context"; @@ -21,18 +18,20 @@ import { clickContinue, } from "./helpers/userActions"; import { PlaywrightEditor } from "./pages/Editor"; -import { - createExternalPortal, - createQuestionWithOptions, -} from "./helpers/addComponent"; +import { createExternalPortal } from "./helpers/addComponent"; import { navigateToService, publishService, turnServiceOnline, } from "./helpers/navigateAndPublish"; +import { TestContext } from "./helpers/types"; +import { + externalPortalFlowData, + externalPortalServiceProps, +} from "./helpers/serviceData"; test.describe("Flow creation, publish and preview", () => { - let context: Context = { + let context: TestContext = { ...contextDefaults, }; const serviceProps = { @@ -67,7 +66,7 @@ test.describe("Flow creation, publish and preview", () => { await editor.addNewService(); // update context to allow flow to be torn down - context.flows = [{ ...serviceProps }]; + context.flow = { ...serviceProps }; await editor.createQuestion(); await editor.createNoticeOnEachBranch(); @@ -131,8 +130,7 @@ test.describe("Flow creation, publish and preview", () => { userId: context.user!.id!, }); - await page.goto(`/${context.team.slug}/${serviceProps.slug}`); - + await navigateToService(page, serviceProps.slug); await publishService(page); const previewLink = page.getByRole("link", { @@ -166,8 +164,7 @@ test.describe("Flow creation, publish and preview", () => { userId: context.user!.id!, }); - await page.goto(`/${context.team.slug}/${serviceProps.slug}`); - + await navigateToService(page, serviceProps.slug); await turnServiceOnline(page); // Exit back to main Editor page @@ -199,24 +196,22 @@ test.describe("Flow creation, publish and preview", () => { await editor.addNewService(); // update context to allow new flow to be torn down - context.flows?.push({ ...externalPortalServiceProps }); + context.externalPortalFlow = { ...externalPortalServiceProps }; + + const { title, answers } = externalPortalFlowData; + + await editor.createQuestionWithOptions(title, answers); - await createQuestionWithOptions( - page, - editor.firstNode, - externalPortalFlowData.title, - externalPortalFlowData.answers, - ); await expect(editor.nodeList).toContainText([ - externalPortalFlowData.title, - externalPortalFlowData.answers[0], - externalPortalFlowData.answers[1], + title, + answers[0], + answers[1], ]); await publishService(page); await turnServiceOnline(page); - navigateToService(page, serviceProps.slug); + await navigateToService(page, serviceProps.slug); await createExternalPortal(page, page.locator("li:nth-child(6)")); diff --git a/e2e/tests/ui-driven/src/helpers/addComponent.ts b/e2e/tests/ui-driven/src/helpers/addComponent.ts index 760f110707..61c0f8ca4e 100644 --- a/e2e/tests/ui-driven/src/helpers/addComponent.ts +++ b/e2e/tests/ui-driven/src/helpers/addComponent.ts @@ -1,6 +1,7 @@ import { ComponentType } from "@opensystemslab/planx-core/types"; import { expect, Locator, Page } from "@playwright/test"; -import { contextDefaults, externalPortalServiceProps } from "./context"; +import { contextDefaults } from "./context"; +import { externalPortalServiceProps } from "./serviceData"; const createBaseComponent = async ( page: Page, diff --git a/e2e/tests/ui-driven/src/helpers/context.ts b/e2e/tests/ui-driven/src/helpers/context.ts index 4356b9c07f..70069ed844 100644 --- a/e2e/tests/ui-driven/src/helpers/context.ts +++ b/e2e/tests/ui-driven/src/helpers/context.ts @@ -3,32 +3,12 @@ import { GraphQLClient, gql } from "graphql-request"; import { sign } from "jsonwebtoken"; import assert from "node:assert"; import { log } from "./globalHelpers"; +import { $admin } from "../../../api-driven/src/client"; +import { Flow, TestContext } from "./types"; -type NewTeam = Parameters[0]; - -export interface Flow { - id?: string; - publishedId?: number; - slug: string; - name: string; - data?: object; -} - -export interface Context { - user: { - id?: number; - firstName: string; - lastName: string; - email: string; - isPlatformAdmin: boolean; - }; - team: { id?: number } & NewTeam; - flows?: Flow[]; - sessionIds?: string[]; -} - -export const contextDefaults: Context = { +export const contextDefaults: TestContext = { user: { + id: 0, firstName: "Test", lastName: "Test", email: "simulate-delivered@notifications.service.gov.uk", @@ -49,10 +29,10 @@ export const contextDefaults: Context = { }; export async function setUpTestContext( - initialContext: Context, -): Promise { + initialContext: TestContext, +): Promise { const $admin = getCoreDomainClient(); - const context: Context = { ...initialContext }; + const context: TestContext = { ...initialContext }; if (context.user) { context.user.id = await $admin.user.create(context.user); } @@ -67,24 +47,24 @@ export async function setUpTestContext( }); } if ( - context.flows && - context.flows[0].slug && - context.flows[0].data && - context.flows[0].name && + context.flow && + context.flow.slug && + context.flow.data && + context.flow.name && context.team?.id && context.user?.id ) { - context.flows[0].id = await $admin.flow.create({ - slug: context.flows[0].slug, - name: context.flows[0].name, + context.flow.id = await $admin.flow.create({ + slug: context.flow.slug, + name: context.flow.name, teamId: context.team.id, - data: context.flows[0].data, + data: context.flow.data, status: "online", }); - context.flows[0].publishedId = await $admin.flow.publish({ + context.flow.publishedId = await $admin.flow.publish({ flow: { - id: context.flows[0].id, - data: context.flows[0].data, + id: context.flow.id, + data: context.flow.data, }, publisherId: context.user!.id!, }); @@ -94,27 +74,10 @@ export async function setUpTestContext( return context; } -export const externalPortalServiceProps = { - name: "An External Portal Service", - slug: "an-external-portal-service", -}; - -export const externalPortalFlowData = { - title: "Is this an External Portal?", - answers: ["It is an external portal", "No it is not an External Portal"], -}; - -export async function tearDownTestContext(context: Context) { +export async function tearDownTestContext(context: TestContext) { const adminGQLClient = getGraphQLClient(); - if (context.flows?.[0]) { - await deleteSession(adminGQLClient, context); - - for (const flow of context.flows) { - await deleteFlow(adminGQLClient, flow); - if (flow.publishedId) { - await deletePublishedFlow(adminGQLClient, flow); - } - } + if (context.flow || context.externalPortalFlow) { + await $admin.flow._destroyAll(); } if (context.user) { await deleteUser(adminGQLClient, context); @@ -170,7 +133,7 @@ export async function findSessionId( id } }`, - { slug: context.flows?.[0].slug }, + { slug: context.flow.slug }, ); if (!flowResponse.flows.length || !flowResponse.flows[0].id) { return; @@ -273,7 +236,7 @@ async function deleteFlow(adminGQLClient: GraphQLClient, flow: Flow) { } } -async function deleteUser(adminGQLClient: GraphQLClient, context: Context) { +async function deleteUser(adminGQLClient: GraphQLClient, context: TestContext) { if (context.user?.id) { log(`deleting user ${context.user?.id}`); await adminGQLClient.request( @@ -310,7 +273,7 @@ async function deleteUser(adminGQLClient: GraphQLClient, context: Context) { } } -async function deleteTeam(adminGQLClient: GraphQLClient, context: Context) { +async function deleteTeam(adminGQLClient: GraphQLClient, context: TestContext) { if (context.team?.id) { log(`deleting team ${context.team?.id}`); await adminGQLClient.request( @@ -347,7 +310,10 @@ async function deleteTeam(adminGQLClient: GraphQLClient, context: Context) { } } -async function setupGovPaySecret($admin: CoreDomainClient, context: Context) { +async function setupGovPaySecret( + $admin: CoreDomainClient, + context: TestContext, +) { try { await $admin.client.request( gql` diff --git a/e2e/tests/ui-driven/src/helpers/globalHelpers.ts b/e2e/tests/ui-driven/src/helpers/globalHelpers.ts index 01a8b0933b..f580449673 100644 --- a/e2e/tests/ui-driven/src/helpers/globalHelpers.ts +++ b/e2e/tests/ui-driven/src/helpers/globalHelpers.ts @@ -1,8 +1,8 @@ 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 { TestContext } from "./types"; // 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 @@ -87,7 +87,7 @@ export async function getSessionId(page: Page): Promise { return sessionId; } -export async function addSessionToContext(page: Page, context: Context) { +export async function addSessionToContext(page: Page, context: TestContext) { const sessionId = await getSessionId(page); context.sessionIds!.push(sessionId); return sessionId; @@ -95,7 +95,7 @@ export async function addSessionToContext(page: Page, context: Context) { export async function waitForPaymentResponse( page: Page, - context: Context, + context: TestContext, ): Promise<{ paymentId: string; state?: { status: string } }> { const { payment_id: paymentId, state } = await page .waitForResponse((response) => { @@ -110,11 +110,11 @@ export async function modifyFlow({ context, modifiedFlow, }: { - context: Context; + context: TestContext; modifiedFlow: FlowGraph; }) { const adminGQLClient = getGraphQLClient(); - if (!context.flows?.[0]?.slug || !context.user?.id) { + if (!context.flow?.slug || !context.user?.id) { throw new Error("context must have a flow and user"); } await adminGQLClient.request( @@ -132,7 +132,7 @@ export async function modifyFlow({ } `, { - flowId: context.flows?.[0].id, + flowId: context.flow?.id, userId: context.user!.id, data: modifiedFlow, }, diff --git a/e2e/tests/ui-driven/src/helpers/navigateAndPublish.ts b/e2e/tests/ui-driven/src/helpers/navigateAndPublish.ts index 1858537eb0..d5d66138fa 100644 --- a/e2e/tests/ui-driven/src/helpers/navigateAndPublish.ts +++ b/e2e/tests/ui-driven/src/helpers/navigateAndPublish.ts @@ -5,8 +5,6 @@ export const navigateToService = async (page: Page, slug: string) => { await page.goto(`/${contextDefaults.team.slug}/${slug}`); await expect(page.getByRole("link", { name: slug })).toBeVisible(); - - return true; }; export const publishService = async (page: Page) => { diff --git a/e2e/tests/ui-driven/src/helpers/serviceData.ts b/e2e/tests/ui-driven/src/helpers/serviceData.ts new file mode 100644 index 0000000000..b1fda6a053 --- /dev/null +++ b/e2e/tests/ui-driven/src/helpers/serviceData.ts @@ -0,0 +1,14 @@ +export const serviceProps = { + name: "A Test Service", + slug: "a-test-service", +}; + +export const externalPortalServiceProps = { + name: "An External Portal Service", + slug: "an-external-portal-service", +}; + +export const externalPortalFlowData = { + title: "Is this an External Portal?", + answers: ["It is an external portal", "No it is not an External Portal"], +}; diff --git a/e2e/tests/ui-driven/src/helpers/types.ts b/e2e/tests/ui-driven/src/helpers/types.ts new file mode 100644 index 0000000000..194f55510d --- /dev/null +++ b/e2e/tests/ui-driven/src/helpers/types.ts @@ -0,0 +1,20 @@ +import { CoreDomainClient } from "@opensystemslab/planx-core"; +import { User } from "@opensystemslab/planx-core/dist/types"; + +type NewTeam = Parameters[0]; + +export interface Flow { + id?: string; + publishedId?: number; + slug: string; + name: string; + data?: object; +} + +export interface TestContext { + user: Omit; + team: { id?: number } & NewTeam; + flow?: Flow; + externalPortalFlow?: Flow; + sessionIds?: string[]; +} diff --git a/e2e/tests/ui-driven/src/helpers/userActions.ts b/e2e/tests/ui-driven/src/helpers/userActions.ts index 703153fb01..35d24d5ae9 100644 --- a/e2e/tests/ui-driven/src/helpers/userActions.ts +++ b/e2e/tests/ui-driven/src/helpers/userActions.ts @@ -1,16 +1,16 @@ import type { Locator, Page } from "@playwright/test"; import { expect } from "@playwright/test"; import { setupOSMockResponse } from "../mocks/osPlacesResponse"; -import type { Context } from "./context"; import { findSessionId, getGraphQLClient } from "./context"; import { TEST_EMAIL, log, waitForDebugLog } from "./globalHelpers"; +import { TestContext } from "./types"; export async function saveSession({ page, context, }: { page: Page; - context: Context; + context: TestContext; }): Promise { const pageResponsePromise = page.waitForResponse((response) => { return response.url().includes("/send-email/save"); @@ -31,11 +31,11 @@ export async function returnToSession({ shouldContinue = true, }: { page: Page; - context: Context; + context: TestContext; sessionId: string; shouldContinue?: boolean; }) { - const returnURL = `/${context.team?.slug}/${context.flows?.[0].slug}/published?analytics=false&sessionId=${sessionId}`; + const returnURL = `/${context.team?.slug}/${context.flow?.slug}/published?analytics=false&sessionId=${sessionId}`; log(`returning to http://localhost:3000/${returnURL}`); await page.goto(returnURL, { waitUntil: "load" }); await page.locator("#email").fill(context.user?.email); @@ -81,7 +81,7 @@ export async function fillInEmail({ context, }: { page: Page; - context: Context; + context: TestContext; }) { await page.locator("#email").fill(context.user.email); await page.locator("#confirmEmail").fill(context.user.email); diff --git a/e2e/tests/ui-driven/src/invite-to-pay/agent.spec.ts b/e2e/tests/ui-driven/src/invite-to-pay/agent.spec.ts index b510e8c1e2..13a915fddc 100644 --- a/e2e/tests/ui-driven/src/invite-to-pay/agent.spec.ts +++ b/e2e/tests/ui-driven/src/invite-to-pay/agent.spec.ts @@ -1,6 +1,5 @@ import { BrowserContext, Page, expect, test } from "@playwright/test"; import { - Context, contextDefaults, getGraphQLClient, setUpTestContext, @@ -20,16 +19,15 @@ import { navigateToPayComponent, } from "./helpers"; import { mockPaymentRequest, modifiedInviteToPayFlow } from "./mocks"; +import { TestContext } from "../helpers/types"; -let context: Context = { +let context: TestContext = { ...contextDefaults, - flows: [ - { - slug: "invite-to-pay-test", - name: "Invite to pay test", - data: inviteToPayFlow, - }, - ], + flow: { + slug: "invite-to-pay-test", + name: "Invite to pay test", + data: inviteToPayFlow, + }, sessionIds: [], // used to collect and clean up sessions }; @@ -108,7 +106,7 @@ test.describe("Agent journey @regression", async () => { const sessionId = await makePaymentRequest({ page: firstPage, context }); // Resume session - const resumeLink = `/${context.team!.slug!}/${context.flows![0].slug}/published?analytics=false&sessionId=${sessionId}`; + const resumeLink = `/${context.team!.slug!}/${context.flow?.slug}/published?analytics=false&sessionId=${sessionId}`; const secondPage = await browserContext.newPage(); await secondPage.goto(resumeLink); await expect( @@ -137,7 +135,7 @@ test.describe("Agent journey @regression", async () => { await modifyFlow({ context, modifiedFlow: modifiedInviteToPayFlow }); // Navigate to resume session link - const resumeLink = `/${context.team!.slug!}/${context.flows![0].slug}/published?analytics=false&sessionId=${sessionId}`; + const resumeLink = `/${context.team!.slug!}/${context.flow?.slug}/published?analytics=false&sessionId=${sessionId}`; const secondPage = await browserContext.newPage(); await secondPage.goto(resumeLink); await expect( diff --git a/e2e/tests/ui-driven/src/invite-to-pay/helpers.ts b/e2e/tests/ui-driven/src/invite-to-pay/helpers.ts index ff7b23239b..b7a21b667d 100644 --- a/e2e/tests/ui-driven/src/invite-to-pay/helpers.ts +++ b/e2e/tests/ui-driven/src/invite-to-pay/helpers.ts @@ -1,7 +1,6 @@ import { PaymentRequest } from "@opensystemslab/planx-core/dist/types"; -import type { Page } from "@playwright/test"; +import { expect, type Page } from "@playwright/test"; import { GraphQLClient, gql } from "graphql-request"; -import { Context } from "../helpers/context"; import { TEST_EMAIL, addSessionToContext, log } from "../helpers/globalHelpers"; import { answerChecklist, @@ -9,13 +8,14 @@ import { answerFindProperty, fillInEmail, } from "../helpers/userActions"; +import { TestContext } from "../helpers/types"; /** * Navigates to pay component whilst completing the minimum requirements for an Invite to Pay flow */ -export async function navigateToPayComponent(page: Page, context: Context) { +export async function navigateToPayComponent(page: Page, context: TestContext) { const previewURL = `/${context.team!.slug!}/${ - context.flows?.[0].slug + context.flow?.slug }/published?analytics=false`; await page.goto(previewURL); @@ -85,7 +85,7 @@ export async function makePaymentRequest({ context, }: { page: Page; - context: Context; + context: TestContext; }) { await navigateToPayComponent(page, context); const sessionId = await addSessionToContext(page, context); @@ -96,6 +96,6 @@ export async function makePaymentRequest({ await answerInviteToPayForm(page); page.getByRole("button", { name: "Send invitation to pay" }).click(); await page.waitForResponse((res) => res.url().includes("invite-to-pay")); - + await expect(page.getByText("Error generating payment")).toBeHidden(); return sessionId; } diff --git a/e2e/tests/ui-driven/src/invite-to-pay/nominee.spec.ts b/e2e/tests/ui-driven/src/invite-to-pay/nominee.spec.ts index 981d6b89aa..f4b8b941b2 100644 --- a/e2e/tests/ui-driven/src/invite-to-pay/nominee.spec.ts +++ b/e2e/tests/ui-driven/src/invite-to-pay/nominee.spec.ts @@ -3,7 +3,6 @@ import { APIRequestContext, Page, expect, test } from "@playwright/test"; import { GraphQLClient, gql } from "graphql-request"; import { v4 as uuidV4 } from "uuid"; import { - Context, contextDefaults, getGraphQLClient, setUpTestContext, @@ -14,16 +13,15 @@ import { fillGovUkCardDetails } from "../helpers/userActions"; import inviteToPayFlow from "../mocks/flows/invite-to-pay-flow"; import { getPaymentRequestBySessionId } from "./helpers"; import { mockPaymentRequestDetails, mockSessionData } from "./mocks"; +import { TestContext } from "../helpers/types"; -let context: Context = { +let context: TestContext = { ...contextDefaults, - flows: [ - { - slug: "invite-to-pay-test", - name: "Invite to pay test", - data: inviteToPayFlow, - }, - ], + flow: { + slug: "invite-to-pay-test", + name: "Invite to pay test", + data: inviteToPayFlow, + }, sessionIds: [], // used to collect and clean up sessions }; @@ -84,8 +82,9 @@ test.describe("Nominee journey @regression", async () => { }); test("navigating to a URL with an invalid ID", async ({ page }) => { - const invalidPaymentRequestURL = `/${context.team!.slug!}/${context - .flows![0].slug!}/pay?analytics=false&paymentRequestId=INVALID-ID`; + const invalidPaymentRequestURL = `/${context.team!.slug!}/${ + context.flow?.slug + }/pay?analytics=false&paymentRequestId=INVALID-ID`; await page.goto(invalidPaymentRequestURL); await page.waitForLoadState("networkidle"); @@ -93,8 +92,7 @@ test.describe("Nominee journey @regression", async () => { }); test("navigating to a URL without a paymentRequestId", async ({ page }) => { - const invalidPaymentRequestURL = `/${context.team!.slug!}/${context - .flows![0].slug!}/pay?analytics=false`; + const invalidPaymentRequestURL = `/${context.team!.slug!}/${context.flow?.slug}/pay?analytics=false`; await page.goto(invalidPaymentRequestURL); await page.waitForLoadState("networkidle"); @@ -128,8 +126,7 @@ async function navigateToPaymentRequestPage( paymentRequest: PaymentRequest, page: Page, ) { - const paymentRequestURL = `/${context.team!.slug!}/${context.flows![0] - .slug!}/pay?analytics=false&paymentRequestId=${paymentRequest.id}`; + const paymentRequestURL = `/${context.team!.slug!}/${context.flow?.slug}/pay?analytics=false&paymentRequestId=${paymentRequest.id}`; await page.goto(paymentRequestURL); await page.waitForLoadState("networkidle"); } @@ -151,7 +148,7 @@ async function createSession({ client, sessionId, }: { - context: Context; + context: TestContext; client: GraphQLClient; sessionId: string; }) { @@ -173,11 +170,11 @@ async function createSession({ await client.request[]>>(mutation, { id: sessionId, data: { - id: context.flows![0].id, + id: context.flow?.id, ...mockSessionData, }, email: context.user.email, - flowId: context.flows![0].id, + flowId: context.flow?.id, }); } diff --git a/e2e/tests/ui-driven/src/login.spec.ts b/e2e/tests/ui-driven/src/login.spec.ts index 23bfbecf83..0f0d73de8d 100644 --- a/e2e/tests/ui-driven/src/login.spec.ts +++ b/e2e/tests/ui-driven/src/login.spec.ts @@ -1,14 +1,14 @@ import { expect, test } from "@playwright/test"; -import type { Context } from "./helpers/context"; import { contextDefaults, setUpTestContext, tearDownTestContext, } from "./helpers/context"; import { createAuthenticatedSession } from "./helpers/globalHelpers"; +import { TestContext } from "./helpers/types"; test.describe("Login", () => { - let context: Context = { + let context: TestContext = { ...contextDefaults, }; diff --git a/e2e/tests/ui-driven/src/pages/Editor.ts b/e2e/tests/ui-driven/src/pages/Editor.ts index 8dd146229f..8e0da26ba5 100644 --- a/e2e/tests/ui-driven/src/pages/Editor.ts +++ b/e2e/tests/ui-driven/src/pages/Editor.ts @@ -74,6 +74,13 @@ export class PlaywrightEditor { ).toBeVisible(); } + async createQuestionWithOptions(title: string, answers: string[]) { + await createQuestionWithOptions(this.page, this.firstNode, title, answers); + await expect( + this.page.locator("a").filter({ hasText: this.answers.questionText }), + ).toBeVisible(); + } + async createNoticeOnEachBranch() { // Add a notice to the "Yes" path await createNotice( diff --git a/e2e/tests/ui-driven/src/pay.spec.ts b/e2e/tests/ui-driven/src/pay.spec.ts index e878ba9ae3..b0a1614870 100644 --- a/e2e/tests/ui-driven/src/pay.spec.ts +++ b/e2e/tests/ui-driven/src/pay.spec.ts @@ -2,7 +2,6 @@ import type { SessionData } from "@opensystemslab/planx-core/types"; import type { Page } from "@playwright/test"; import { expect, test } from "@playwright/test"; import { GraphQLClient, gql } from "graphql-request"; -import type { Context } from "./helpers/context"; import { contextDefaults, getGraphQLClient, @@ -17,20 +16,19 @@ import { } from "./helpers/globalHelpers"; import { fillGovUkCardDetails, submitCardDetails } from "./helpers/userActions"; import payFlow from "./mocks/flows/pay-flow.json"; +import { TestContext } from "./helpers/types"; -let context: Context = { +let context: TestContext = { ...contextDefaults, - flows: [ - { - slug: "pay-test", - name: "Pay test", - data: payFlow, - }, - ], + flow: { + slug: "pay-test", + name: "Pay test", + data: payFlow, + }, + sessionIds: [], // used to collect and clean up sessions }; -const previewURL = `/${context.team!.slug!}/${context.flows![0] - .slug!}/published?analytics=false`; +const previewURL = `/${context.team!.slug!}/${context.flow?.slug}/published?analytics=false`; const payButtonText = "Pay now using GOV.UK Pay"; diff --git a/e2e/tests/ui-driven/src/refresh-page.spec.ts b/e2e/tests/ui-driven/src/refresh-page.spec.ts index 4edd79c190..37481963be 100644 --- a/e2e/tests/ui-driven/src/refresh-page.spec.ts +++ b/e2e/tests/ui-driven/src/refresh-page.spec.ts @@ -1,5 +1,4 @@ import { expect, test } from "@playwright/test"; -import type { Context } from "./helpers/context"; import { contextDefaults, setUpTestContext, @@ -9,9 +8,10 @@ import { createAuthenticatedSession, isGetUserRequest, } from "./helpers/globalHelpers"; +import { TestContext } from "./helpers/types"; test.describe("Refresh page", () => { - let context: Context = { + let context: TestContext = { ...contextDefaults, }; diff --git a/e2e/tests/ui-driven/src/save-and-return.spec.ts b/e2e/tests/ui-driven/src/save-and-return.spec.ts index 5703e0c598..9631fc177a 100644 --- a/e2e/tests/ui-driven/src/save-and-return.spec.ts +++ b/e2e/tests/ui-driven/src/save-and-return.spec.ts @@ -1,5 +1,4 @@ import { expect, test } from "@playwright/test"; -import type { Context } from "./helpers/context"; import { contextDefaults, setUpTestContext, @@ -18,19 +17,18 @@ import { modifiedSimpleSendFlow, simpleSendFlow, } from "./mocks/flows/save-and-return-flows"; +import { TestContext } from "./helpers/types"; test.describe("Save and return", () => { - let context: Context = { + let context: TestContext = { ...contextDefaults, - flows: [ - { - slug: "e2e-save-and-return-test-flow", - name: "E2E Save and Return test flow", - data: simpleSendFlow, - }, - ], + flow: { + slug: "e2e-save-and-return-test-flow", + name: "E2E Save and Return test flow", + data: simpleSendFlow, + }, }; - const previewURL = `/${context.team?.slug}/${context.flows![0].slug}/published?analytics=false`; + const previewURL = `/${context.team?.slug}/${context.flow?.slug}/published?analytics=false`; test.beforeAll(async () => { try { diff --git a/e2e/tests/ui-driven/src/sections.spec.ts b/e2e/tests/ui-driven/src/sections.spec.ts index 2961a8f9c1..159cc99c34 100644 --- a/e2e/tests/ui-driven/src/sections.spec.ts +++ b/e2e/tests/ui-driven/src/sections.spec.ts @@ -1,7 +1,6 @@ import type { FlowGraph } from "@opensystemslab/planx-core/types"; import { expect, test } from "@playwright/test"; import { gql } from "graphql-request"; -import type { Context } from "./helpers/context"; import { contextDefaults, getGraphQLClient, @@ -21,6 +20,7 @@ import { saveSession, } from "./helpers/userActions"; import { flow, updatedQuestionAnswers } from "./mocks/flows/sections-flow"; +import { TestContext } from "./helpers/types"; // TODO: move this type to planx-core // also defined in editor.planx.uk/src/types.ts @@ -34,15 +34,13 @@ export enum SectionStatus { } test.describe("Section statuses", () => { - let context: Context = { + let context: TestContext = { ...contextDefaults, - flows: [ - { - slug: "sections-test-flow", - name: "Sections test flow", - data: flow, - }, - ], + flow: { + slug: "sections-test-flow", + name: "Sections test flow", + data: flow, + }, }; test.beforeAll(async () => { @@ -55,7 +53,7 @@ test.describe("Section statuses", () => { }); test.beforeEach(async ({ page }) => { - const previewURL = `/${context.team?.slug}/${context.flows![0].slug}/published?analytics=false`; + const previewURL = `/${context.team?.slug}/${context.flow?.slug}/published?analytics=false`; await page.goto(previewURL); }); @@ -533,11 +531,11 @@ async function modifyFlow({ context, flowData, }: { - context: Context; + context: TestContext; flowData: FlowGraph; }) { const adminGQLClient = getGraphQLClient(); - if (!context.flows![0].id || !context.user?.id) { + if (!context.flow?.id || !context.user?.id) { throw new Error("context must have a flow and user"); } await adminGQLClient.request( @@ -555,7 +553,7 @@ async function modifyFlow({ } `, { - flowId: context.flows![0].id, + flowId: context.flow?.id, userId: context.user!.id, data: flowData, },