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 16b46b755e..098c914a85 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 @@ -62,6 +62,8 @@ test.describe("Flow creation, publish and preview", () => { }); test("Create a flow", async ({ browser }) => { + test.setTimeout(60_000); + const page = await getTeamPage({ browser, userId: context.user!.id!, @@ -107,6 +109,8 @@ test.describe("Flow creation, publish and preview", () => { test("Publish and preview flow with geospatial components", async ({ browser, }) => { + test.setTimeout(60_000); + const page = await createAuthenticatedSession({ browser, userId: context.user!.id!, diff --git a/e2e/tests/ui-driven/src/create-flow.spec.ts b/e2e/tests/ui-driven/src/create-flow.spec.ts index 921e2a54a9..ffb4419353 100644 --- a/e2e/tests/ui-driven/src/create-flow.spec.ts +++ b/e2e/tests/ui-driven/src/create-flow.spec.ts @@ -58,6 +58,8 @@ test.describe("Flow creation, publish and preview", () => { }); test("Create a flow", async ({ browser }) => { + test.setTimeout(60_000); + const page = await getTeamPage({ browser, userId: context.user!.id!, @@ -231,7 +233,7 @@ test.describe("Flow creation, publish and preview", () => { await publishService(page); }); - test("Can preview a published flow", async ({ + test("Can preview a published flow with an external portal", async ({ browser, }: { browser: Browser; @@ -241,12 +243,17 @@ 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 expect( page.getByRole("link", { name: "E2E/an-external-portal-service" }), ).toBeVisible(); + const previewLink = page.getByRole("link", { + name: "Open published service", + }); + await expect(previewLink).toBeVisible(); + await page.goto( `/${context.team.slug}/${serviceProps.slug}/published?analytics=false`, ); @@ -273,6 +280,7 @@ test.describe("Flow creation, publish and preview", () => { }); await clickContinue({ page }); + // The external portal question has been flattened into the overall flow data structure and can be successfully navigated through await answerQuestion({ page, title: externalPortalFlowData.title, diff --git a/e2e/tests/ui-driven/src/helpers/addComponent.ts b/e2e/tests/ui-driven/src/helpers/addComponent.ts index 7f9c6f10b3..b3140c7f92 100644 --- a/e2e/tests/ui-driven/src/helpers/addComponent.ts +++ b/e2e/tests/ui-driven/src/helpers/addComponent.ts @@ -55,11 +55,19 @@ const createBaseComponent = async ( break; case ComponentType.AddressInput: await page.getByPlaceholder("Title").fill(title || ""); - await page.getByPlaceholder("Data Field").fill(options?.[0] || ""); + await page.getByRole("combobox", { name: "Data field" }).click(); + await page + .getByRole("combobox", { name: "Data field" }) + .fill(options?.[0] || "proposal.address"); + await page.getByRole("combobox", { name: "Data field" }).press("Enter"); break; case ComponentType.ContactInput: await page.getByPlaceholder("Title").fill(title || ""); - await page.getByPlaceholder("Data Field").fill(options?.[0] || ""); + await page.getByRole("combobox", { name: "Data field" }).click(); + await page + .getByRole("combobox", { name: "Data field" }) + .fill(options?.[0] || "proposal.contact"); + await page.getByRole("combobox", { name: "Data field" }).press("Enter"); break; case ComponentType.TaskList: await page.getByPlaceholder("Main Title").fill(title || ""); @@ -112,15 +120,27 @@ const createBaseComponent = async ( } break; case ComponentType.FileUpload: - await page.getByPlaceholder("Data Field").fill(options?.[0] || ""); + await page.getByRole("combobox", { name: "Data field" }).click(); + await page + .getByRole("combobox", { name: "Data field" }) + .fill(options?.[0] || "otherDocument"); + await page.getByRole("combobox", { name: "Data field" }).press("Enter"); break; case ComponentType.FileUploadAndLabel: await page.getByPlaceholder("File type").fill(options?.[0] || ""); - await page.getByPlaceholder("Data Field").fill(options?.[1] || ""); + await page.getByRole("combobox", { name: "Data field" }).click(); + await page + .getByRole("combobox", { name: "Data field" }) + .fill(options?.[1] || "otherDocument"); + await page.getByRole("combobox", { name: "Data field" }).press("Enter"); break; case ComponentType.List: await page.getByPlaceholder("Title").fill(title || ""); - await page.getByPlaceholder("Data Field").fill(options?.[0] || ""); + await page.getByRole("combobox", { name: "Data field" }).click(); + await page + .getByRole("combobox", { name: "Data field" }) + .fill(options?.[0] || "proposal.list"); + await page.getByRole("combobox", { name: "Data field" }).press("Enter"); break; case ComponentType.Content: await page @@ -176,7 +196,9 @@ export const createQuestionWithDataFieldOptions = async ( await locatingNode.click(); await page.getByRole("dialog").waitFor(); await page.getByPlaceholder("Text").fill(questionText); - await page.getByPlaceholder("Data Field").fill(dataField); + await page.getByRole("combobox", { name: "Data field" }).click(); + await page.getByRole("combobox", { name: "Data field" }).fill(dataField); + await page.getByRole("combobox", { name: "Data field" }).press("Enter"); await createComponentOptionsWithDataValues(page, options); await page.locator('button[form="modal"][type="submit"]').click(); }; @@ -377,12 +399,13 @@ async function createComponentOptionsWithDataValues( page: Page, options: OptionWithDataValues[], ) { - let index = 0; for (const option of options) { await page.locator("button").filter({ hasText: "add new" }).click(); - await page.getByPlaceholder("Option").nth(index).fill(option.optionText); - await page.getByPlaceholder("Data Value").nth(index).fill(option.dataValue); - index++; + await page.getByPlaceholder("Option").last().fill(option.optionText); + await page.getByRole("combobox", { name: "Data field" }).last().click(); + await page + .getByRole("option", { name: option.dataValue, exact: true }) + .click(); } } diff --git a/e2e/tests/ui-driven/src/helpers/userActions.ts b/e2e/tests/ui-driven/src/helpers/userActions.ts index 6229183c02..f70a4d3bb3 100644 --- a/e2e/tests/ui-driven/src/helpers/userActions.ts +++ b/e2e/tests/ui-driven/src/helpers/userActions.ts @@ -328,14 +328,14 @@ export async function answerListInput( await page .getByRole("combobox", { name: "What best describes this unit?" }) .click(); - await page.getByRole("option", { name: unitType }).click(); + await page.getByRole("option", { name: unitType, exact: true }).click(); await page .getByRole("combobox", { name: "What best describes the tenure of this unit?", }) .click(); - await page.getByRole("option", { name: tenure }).click(); + await page.getByRole("option", { name: tenure, exact: true }).click(); await page .getByLabel("How many bedrooms does this unit have?") diff --git a/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx b/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx index 35a9a643a1..839f45a51c 100644 --- a/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx +++ b/editor.planx.uk/src/@planx/components/AddressInput/Editor.tsx @@ -9,6 +9,7 @@ import RichTextInput from "ui/editor/RichTextInput/RichTextInput"; import Input from "ui/shared/Input/Input"; import InputRow from "ui/shared/InputRow"; +import { DataFieldAutocomplete } from "../shared/DataFieldAutocomplete"; import { ICONS } from "../shared/icons"; import { AddressInput, parseAddressInput } from "./model"; @@ -25,8 +26,9 @@ export default function AddressInputComponent(props: Props): FCReturn { }); } }, - validate: () => {}, + validate: () => { }, }); + return (