diff --git a/api.planx.uk/.husky/pre-commit b/api.planx.uk/.husky/pre-commit
index 58eb265738..2dca158161 100755
--- a/api.planx.uk/.husky/pre-commit
+++ b/api.planx.uk/.husky/pre-commit
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd api.planx.uk
-pnpm dlx lint-staged
\ No newline at end of file
+pnpm dlx lint-staged
diff --git a/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts b/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts
index 0db5895bcc..d3eda04740 100644
--- a/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts
+++ b/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts
@@ -1,21 +1,4 @@
import { Browser, expect, test } from "@playwright/test";
-import {
- createAddressInput,
- createChecklist,
- createContactInput,
- createDateInput,
- createDrawBoundary,
- createFileUpload,
- createFindProperty,
- createNextSteps,
- createNotice,
- createNumberInput,
- createPlanningConstraints,
- createQuestionWithOptions,
- createReview,
- createTaskList,
- createTextInput,
-} from "../helpers/addComponent";
import type { Context } from "../helpers/context";
import {
contextDefaults,
@@ -23,13 +6,21 @@ import {
tearDownTestContext,
} from "../helpers/context";
import { getTeamPage } from "../helpers/getPage";
+import { createAuthenticatedSession } from "../helpers/globalHelpers";
import {
- createAuthenticatedSession,
- isGetUserRequest,
-} from "../helpers/globalHelpers";
-import { answerQuestion, clickContinue } from "../helpers/userActions";
-
-test.describe("Navigation", () => {
+ answerAddressInput,
+ answerChecklist,
+ answerContactInput,
+ answerDateInput,
+ answerFindProperty,
+ answerNumberInput,
+ answerQuestion,
+ answerTextInput,
+ clickContinue,
+} from "../helpers/userActions";
+import { PlaywrightEditor } from "../pages/Editor";
+
+test.describe("Flow creation, publish and preview", () => {
let context: Context = {
...contextDefaults,
};
@@ -52,60 +43,6 @@ test.describe("Navigation", () => {
await tearDownTestContext(context);
});
- test("user data persists on page refresh @regression", async ({
- browser,
- }) => {
- const page = await createAuthenticatedSession({
- browser,
- userId: context.user!.id!,
- });
-
- const initialRequest = page.waitForRequest(isGetUserRequest);
-
- Promise.all([await page.goto("/"), await initialRequest]);
-
- const team = page.locator("h3", { hasText: context.team.name });
-
- let isRepeatedRequestMade = false;
- page.on(
- "request",
- (req) => (isRepeatedRequestMade = isGetUserRequest(req)),
- );
-
- Promise.all([
- await team.click(),
- expect(isRepeatedRequestMade).toBe(false),
- ]);
-
- const reloadRequest = page.waitForRequest(isGetUserRequest);
-
- Promise.all([await page.reload(), await reloadRequest]);
- });
-
- test("team data persists on page refresh @regression", async ({
- browser,
- }) => {
- const page = await createAuthenticatedSession({
- browser,
- userId: context.user!.id!,
- });
-
- await page.goto("/");
- const team = page.locator("h3", { hasText: context.team.name });
- await team.click();
-
- const teamSlugInHeader = page.getByRole("link", {
- name: context.team.slug,
- });
- await expect(teamSlugInHeader).toBeVisible();
-
- await page.reload();
- await expect(teamSlugInHeader).toBeVisible();
-
- await page.goBack();
- await expect(teamSlugInHeader).toBeHidden();
- });
-
test("Create a flow", async ({ browser }) => {
const page = await getTeamPage({
browser,
@@ -113,105 +50,48 @@ test.describe("Navigation", () => {
teamName: context.team.name,
});
+ const editor = new PlaywrightEditor(page);
+
page.on("dialog", (dialog) => dialog.accept(serviceProps.name));
- await page.locator("button", { hasText: "Add a new service" }).click();
+ await editor.addNewService();
// update context to allow flow to be torn down
context.flow = { ...serviceProps };
- const firstNode = page.locator("li.hanger > a").first();
-
- const questionText = "Is this a test?";
- await createQuestionWithOptions(page, firstNode, questionText, [
- "Yes",
- "No",
- ]);
- await expect(
- page.locator("a").filter({ hasText: questionText }),
- ).toBeVisible();
-
- // Add a notice to the "Yes" path
- const yesBranch = page.locator("#flow .card .options .option").nth(0);
-
- const yesBranchNoticeText = "Yes! this is a test";
- await createNotice(
- page,
- yesBranch.locator(".hanger > a"),
- yesBranchNoticeText,
- );
-
- // Add a notice to the "No" path
- const noBranch = page.locator("#flow .card .options .option").nth(1);
- const noBranchNoticeText = "Sorry, this is a test";
- await createNotice(
- page,
- noBranch.locator(".hanger > a"),
- noBranchNoticeText,
- );
-
- const getNextNode = () => page.locator(".hanger > a").last();
-
- await createChecklist(page, getNextNode(), "A checklist title", [
+ await editor.createQuestion();
+ await editor.createNoticeOnEachBranch();
+ await editor.createChecklist();
+ await editor.createTextInput();
+ await editor.createNumberInput();
+ await editor.createDateInput();
+ await editor.createAddressInput();
+ await editor.createContactInput();
+ await editor.createTaskList();
+ await editor.createFindProperty();
+ await editor.createDrawBoundary();
+ await editor.createPlanningConstraints();
+ await editor.createFileUpload();
+ await editor.createNextSteps();
+ await editor.createReview();
+
+ await expect(editor.nodeList).toContainText([
+ "Is this a test?",
+ "Yes! this is a test",
+ "Sorry, this is a test",
"Checklist item 1",
- "Second checklist item",
- "The third checklist item",
- ]);
-
- await createTextInput(page, getNextNode(), "Tell us about your trees.");
- await createNumberInput(page, getNextNode(), "How old are you?", "years");
- await createDateInput(page, getNextNode(), "When is your birthday?");
-
- await createAddressInput(
- page,
- getNextNode(),
+ "Tell us about your trees.",
+ "How old are you?",
+ "When is your birthday?",
"What is your address?",
- "some data field",
- );
-
- await createContactInput(
- page,
- getNextNode(),
"What is your contact info?",
- "some data field",
- );
-
- await createTaskList(page, getNextNode(), "What you should do next", [
- "Have a cup of tea",
- "Continue through this flow",
- ]);
-
- await createFindProperty(page, getNextNode());
- await createDrawBoundary(page, getNextNode());
- await createPlanningConstraints(page, getNextNode());
- await createFileUpload(page, getNextNode(), "some data field");
-
- await createNextSteps(page, getNextNode(), [
- "A possible next step",
- "Another option",
+ "What you should do next",
+ "Find property",
+ "Confirm your location plan",
+ "Planning constraints",
+ "File upload",
+ "Next steps",
+ "Check your answers before sending your application",
]);
-
- await createReview(page, getNextNode());
-
- const nodes = page.locator(".card");
- await expect(nodes.getByText(questionText)).toBeVisible();
- await expect(nodes.getByText(yesBranchNoticeText)).toBeVisible();
- await expect(nodes.getByText(noBranchNoticeText)).toBeVisible();
- await expect(nodes.getByText("Checklist item 1")).toBeVisible();
- await expect(nodes.getByText("Tell us about your trees.")).toBeVisible();
- await expect(nodes.getByText("How old are you?")).toBeVisible();
- await expect(nodes.getByText("When is your birthday?")).toBeVisible();
- await expect(nodes.getByText("What is your address?")).toBeVisible();
- await expect(nodes.getByText("What is your contact info?")).toBeVisible();
- await expect(nodes.getByText("What you should do next")).toBeVisible();
- await expect(nodes.getByText("Find property")).toBeVisible();
- await expect(nodes.getByText("Confirm your location plan")).toBeVisible();
- await expect(nodes.getByText("Planning constraints")).toBeVisible();
- await expect(nodes.getByText("File upload")).toBeVisible();
-
- await expect(nodes.getByText("Next steps")).toBeVisible();
- await expect(
- nodes.getByText("Check your answers before sending your application"),
- ).toBeVisible();
});
test("Cannot preview an unpublished flow", async ({
@@ -321,5 +201,66 @@ test.describe("Navigation", () => {
await expect(
page.locator("h1", { hasText: "Sorry, this is a test" }),
).toBeVisible();
+ await clickContinue({ page });
+
+ await answerChecklist({
+ page,
+ title: "A checklist title",
+ answers: ["Checklist item 1", "Second checklist item"],
+ });
+ await clickContinue({ page });
+
+ await answerTextInput(page, {
+ expectedQuestion: "Tell us about your trees.",
+ answer: "My trees are lovely",
+ continueToNext: true,
+ });
+
+ await answerNumberInput(page, {
+ expectedQuestion: "How old are you?",
+ answer: 30,
+ continueToNext: true,
+ });
+
+ await answerDateInput(page, {
+ expectedQuestion: "When is your birthday?",
+ day: 30,
+ month: 12,
+ year: 1980,
+ continueToNext: true,
+ });
+
+ await answerAddressInput(page, {
+ expectedQuestion: "What is your address?",
+ addressLineOne: "1 Silver Street",
+ town: "Bamburgh",
+ postcode: "BG1 2SS",
+ continueToNext: true,
+ });
+
+ await expect(
+ page.locator("h1", { hasText: "What is your contact info?" }),
+ ).toBeVisible();
+ await answerContactInput(page, {
+ firstName: "Freddie",
+ lastName: "Mercury",
+ phoneNumber: "01234 555555",
+ email: "freddie@queen.com",
+ });
+ await clickContinue({ page });
+
+ await expect(
+ page.locator("h1", { hasText: "What you should do next" }),
+ ).toBeVisible();
+ await expect(
+ page.locator("h2", { hasText: "Have a cup of tea" }),
+ ).toBeVisible();
+ await expect(
+ page.locator("h2", { hasText: "Continue through this flow" }),
+ ).toBeVisible();
+ await clickContinue({ page });
+
+ await answerFindProperty(page);
+ await clickContinue({ page });
});
});
diff --git a/e2e/tests/ui-driven/src/helpers/userActions.ts b/e2e/tests/ui-driven/src/helpers/userActions.ts
index bb2a048125..51c7cbe7ca 100644
--- a/e2e/tests/ui-driven/src/helpers/userActions.ts
+++ b/e2e/tests/ui-driven/src/helpers/userActions.ts
@@ -1,6 +1,6 @@
import type { Locator, Page } from "@playwright/test";
import { expect } from "@playwright/test";
-import { mockOSPlacesResponse } from "../mocks/osPlacesResponse";
+import { setupOSMockResponse } from "../mocks/osPlacesResponse";
import type { Context } from "./context";
import { findSessionId, getGraphQLClient } from "./context";
import { TEST_EMAIL, log, waitForDebugLog } from "./globalHelpers";
@@ -121,7 +121,7 @@ export async function answerChecklist({
title: string;
answers: string[];
}) {
- const checklist = await page.getByRole("heading").filter({
+ const checklist = page.getByRole("heading").filter({
hasText: title,
});
await expect(checklist).toBeVisible();
@@ -196,23 +196,14 @@ export async function submitCardDetails(page: Page) {
export async function answerFindProperty(page: Page) {
await setupOSMockResponse(page);
+ await expect(
+ page.locator("h1", { hasText: "Find the property" }),
+ ).toBeVisible();
await page.getByLabel("Postcode").fill("SW1 1AA");
await page.getByLabel("Select an address").click();
await page.getByRole("option").first().click();
}
-async function setupOSMockResponse(page: Page) {
- const ordnanceSurveryPlacesEndpoint = new RegExp(
- /proxy\/ordnance-survey\/search\/places\/v1\/postcode\/*/,
- );
- await page.route(ordnanceSurveryPlacesEndpoint, async (route) => {
- await route.fulfill({
- status: 200,
- body: JSON.stringify(mockOSPlacesResponse),
- });
- });
-}
-
export async function answerContactInput(
page: Page,
{
@@ -232,3 +223,96 @@ export async function answerContactInput(
await page.getByLabel("Phone number").fill(phoneNumber);
await page.getByLabel("Email address").fill(email);
}
+
+export async function answerTextInput(
+ page: Page,
+ {
+ expectedQuestion,
+ answer,
+ continueToNext,
+ }: {
+ expectedQuestion: string;
+ answer: string;
+ continueToNext: boolean;
+ },
+) {
+ await expect(page.locator("p", { hasText: expectedQuestion })).toBeVisible();
+ await page.locator("label div input[type='text']").fill(answer);
+ if (continueToNext) {
+ await clickContinue({ page });
+ }
+}
+
+export async function answerNumberInput(
+ page: Page,
+ {
+ expectedQuestion,
+ answer,
+ continueToNext,
+ }: {
+ expectedQuestion: string;
+ answer: number;
+ continueToNext: boolean;
+ },
+) {
+ await expect(page.locator("p", { hasText: expectedQuestion })).toBeVisible();
+ await page.locator("label div input[type='number']").fill(answer.toString());
+ if (continueToNext) {
+ await clickContinue({ page });
+ }
+}
+
+export async function answerDateInput(
+ page: Page,
+ {
+ expectedQuestion,
+
+ day,
+ month,
+ year,
+ continueToNext,
+ }: {
+ expectedQuestion: string;
+
+ day: number;
+ month: number;
+ year: number;
+ continueToNext: boolean;
+ },
+) {
+ await expect(page.locator("h1", { hasText: expectedQuestion })).toBeVisible();
+ await page.getByLabel("Day").fill(day.toString());
+ await page.getByLabel("Month").fill(month.toString());
+ await page.getByLabel("Year").fill(year.toString());
+
+ if (continueToNext) {
+ await clickContinue({ page });
+ }
+}
+
+export async function answerAddressInput(
+ page: Page,
+ {
+ expectedQuestion,
+
+ addressLineOne,
+ town,
+ postcode,
+ continueToNext,
+ }: {
+ expectedQuestion: string;
+
+ addressLineOne: string;
+ town: string;
+ postcode: string;
+ continueToNext: boolean;
+ },
+) {
+ await expect(page.locator("h1", { hasText: expectedQuestion })).toBeVisible();
+ await page.getByLabel("Address line 1").fill(addressLineOne);
+ await page.getByLabel("Town").fill(town);
+ await page.getByLabel("Postcode").fill(postcode);
+ if (continueToNext) {
+ await clickContinue({ page });
+ }
+}
diff --git a/e2e/tests/ui-driven/src/mocks/osPlacesResponse.ts b/e2e/tests/ui-driven/src/mocks/osPlacesResponse.ts
index 6b6baf7d4b..5f4547be28 100644
--- a/e2e/tests/ui-driven/src/mocks/osPlacesResponse.ts
+++ b/e2e/tests/ui-driven/src/mocks/osPlacesResponse.ts
@@ -1,3 +1,5 @@
+import { Page } from "@playwright/test";
+
export const mockOSPlacesResponse = {
header: {
uri: "https://api.os.uk/search/places/v1/postcode?postcode=SW1%201AA&dataset=LPI&maxResults=100&output_srs=EPSG%3A4326&lr=EN&offset=0",
@@ -58,3 +60,14 @@ export const mockOSPlacesResponse = {
},
],
};
+export async function setupOSMockResponse(page: Page) {
+ const ordnanceSurveryPlacesEndpoint = new RegExp(
+ /proxy\/ordnance-survey\/search\/places\/v1\/postcode\/*/,
+ );
+ await page.route(ordnanceSurveryPlacesEndpoint, async (route) => {
+ await route.fulfill({
+ status: 200,
+ body: JSON.stringify(mockOSPlacesResponse),
+ });
+ });
+}
diff --git a/e2e/tests/ui-driven/src/pages/Editor.ts b/e2e/tests/ui-driven/src/pages/Editor.ts
new file mode 100644
index 0000000000..accbd03265
--- /dev/null
+++ b/e2e/tests/ui-driven/src/pages/Editor.ts
@@ -0,0 +1,174 @@
+import { expect, type Locator, type Page } from "@playwright/test";
+import {
+ createAddressInput,
+ createChecklist,
+ createContactInput,
+ createDateInput,
+ createDrawBoundary,
+ createFileUpload,
+ createFindProperty,
+ createNextSteps,
+ createNotice,
+ createNumberInput,
+ createPlanningConstraints,
+ createQuestionWithOptions,
+ createReview,
+ createTaskList,
+ createTextInput,
+} from "../helpers/addComponent";
+
+export class PlaywrightEditor {
+ readonly page: Page;
+ readonly addNewServiceButton: Locator;
+ readonly firstNode: Locator;
+ readonly yesBranch: Locator;
+ readonly noBranch: Locator;
+ readonly nodeList: Locator;
+ readonly answers: {
+ questionText: string;
+ yesBranchNoticeText: string;
+ noBranchNoticeText: string;
+ };
+
+ constructor(page: Page) {
+ this.page = page;
+ this.addNewServiceButton = page.locator("button", {
+ hasText: "Add a new service",
+ });
+ this.firstNode = page.locator("li.hanger > a").first();
+ this.yesBranch = page.locator("#flow .card .options .option").nth(0);
+ this.noBranch = page.locator("#flow .card .options .option").nth(1);
+ this.nodeList = page.locator(".card");
+ this.answers = {
+ questionText: "Is this a test?",
+ yesBranchNoticeText: "Yes! this is a test",
+ noBranchNoticeText: "Sorry, this is a test",
+ };
+ }
+
+ async addNewService() {
+ await this.addNewServiceButton.click();
+ }
+
+ async createQuestion() {
+ await createQuestionWithOptions(
+ this.page,
+ this.firstNode,
+ this.answers.questionText,
+ ["Yes", "No"],
+ );
+ await expect(
+ this.page.locator("a").filter({ hasText: this.answers.questionText }),
+ ).toBeVisible();
+ }
+
+ async createNoticeOnEachBranch() {
+ // Add a notice to the "Yes" path
+ await createNotice(
+ this.page,
+ this.yesBranch.locator(".hanger > a"),
+ this.answers.yesBranchNoticeText,
+ );
+ // Add a notice to the "No" path
+ await createNotice(
+ this.page,
+ this.noBranch.locator(".hanger > a"),
+ this.answers.noBranchNoticeText,
+ );
+
+ await expect(
+ this.page.locator("a").filter({ hasText: this.answers.questionText }),
+ ).toBeVisible();
+ }
+
+ getNextNode() {
+ return this.page.locator(".hanger > a").last();
+ }
+
+ async createChecklist() {
+ await createChecklist(this.page, this.getNextNode(), "A checklist title", [
+ "Checklist item 1",
+ "Second checklist item",
+ "The third checklist item",
+ ]);
+ }
+
+ async createTextInput() {
+ await createTextInput(
+ this.page,
+ this.getNextNode(),
+ "Tell us about your trees.",
+ );
+ }
+
+ async createNumberInput() {
+ await createNumberInput(
+ this.page,
+ this.getNextNode(),
+ "How old are you?",
+ "years",
+ );
+ }
+
+ async createDateInput() {
+ await createDateInput(
+ this.page,
+ this.getNextNode(),
+ "When is your birthday?",
+ );
+ }
+
+ async createAddressInput() {
+ await createAddressInput(
+ this.page,
+ this.getNextNode(),
+ "What is your address?",
+ "some data field",
+ );
+ }
+
+ async createContactInput() {
+ await createContactInput(
+ this.page,
+ this.getNextNode(),
+ "What is your contact info?",
+ "some data field",
+ );
+ }
+
+ async createTaskList() {
+ await createTaskList(
+ this.page,
+ this.getNextNode(),
+ "What you should do next",
+ ["Have a cup of tea", "Continue through this flow"],
+ );
+ }
+
+ async createFindProperty() {
+ await createFindProperty(this.page, this.getNextNode());
+ }
+
+ async createDrawBoundary() {
+ await createDrawBoundary(this.page, this.getNextNode());
+ }
+
+ async createPlanningConstraints() {
+ await createPlanningConstraints(this.page, this.getNextNode());
+ }
+
+ async createFileUpload() {
+ await createFileUpload(this.page, this.getNextNode(), "some data field");
+ }
+
+ async createNextSteps() {
+ await createNextSteps(this.page, this.getNextNode(), [
+ "A possible next step",
+ "Another option",
+ ]);
+ }
+
+ async createReview() {
+ await createReview(this.page, this.getNextNode());
+ }
+}
diff --git a/e2e/tests/ui-driven/src/refresh-page.spec.ts b/e2e/tests/ui-driven/src/refresh-page.spec.ts
new file mode 100644
index 0000000000..309d09c0f4
--- /dev/null
+++ b/e2e/tests/ui-driven/src/refresh-page.spec.ts
@@ -0,0 +1,85 @@
+import { expect, test } from "@playwright/test";
+import type { Context } from "./helpers/context";
+import {
+ contextDefaults,
+ setUpTestContext,
+ tearDownTestContext,
+} from "./helpers/context";
+import {
+ createAuthenticatedSession,
+ isGetUserRequest,
+} from "./helpers/globalHelpers";
+
+test.describe("Refresh page", () => {
+ 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("user data persists on page refresh @regression", async ({
+ browser,
+ }) => {
+ const page = await createAuthenticatedSession({
+ browser,
+ userId: context.user!.id!,
+ });
+
+ const initialRequest = page.waitForRequest(isGetUserRequest);
+
+ Promise.all([await page.goto("/"), await initialRequest]);
+
+ const team = page.locator("h3", { hasText: context.team.name });
+
+ let isRepeatedRequestMade = false;
+ page.on(
+ "request",
+ (req) => (isRepeatedRequestMade = isGetUserRequest(req)),
+ );
+
+ Promise.all([
+ await team.click(),
+ expect(isRepeatedRequestMade).toBe(false),
+ ]);
+
+ const reloadRequest = page.waitForRequest(isGetUserRequest);
+
+ Promise.all([await page.reload(), await reloadRequest]);
+ });
+
+ test("team data persists on page refresh @regression", async ({
+ browser,
+ }) => {
+ const page = await createAuthenticatedSession({
+ browser,
+ userId: context.user!.id!,
+ });
+
+ await page.goto("/");
+ const team = page.locator("h3", { hasText: context.team.name });
+ await team.click();
+
+ const teamSlugInHeader = page.getByRole("link", {
+ name: context.team.slug,
+ });
+ await expect(teamSlugInHeader).toBeVisible();
+
+ await page.reload();
+ await expect(teamSlugInHeader).toBeVisible();
+
+ await page.goBack();
+ await expect(teamSlugInHeader).toBeHidden();
+ });
+});
diff --git a/editor.planx.uk/src/@planx/components/MapAndLabel/Public/index.test.tsx b/editor.planx.uk/src/@planx/components/MapAndLabel/Public/index.test.tsx
index 5d0cdcd880..5addd9b4c3 100644
--- a/editor.planx.uk/src/@planx/components/MapAndLabel/Public/index.test.tsx
+++ b/editor.planx.uk/src/@planx/components/MapAndLabel/Public/index.test.tsx
@@ -60,14 +60,14 @@ describe("Basic UI", () => {
await waitFor(() =>
expect(
- queryByText("Plot a feature on the map to begin")
- ).not.toBeInTheDocument()
+ queryByText("Plot a feature on the map to begin"),
+ ).not.toBeInTheDocument(),
);
});
it("renders the schema name as the tab title", async () => {
const { queryByText, getByRole, getByTestId } = setup(
-
+ ,
);
expect(queryByText(/Tree 1/)).not.toBeInTheDocument();
@@ -81,7 +81,7 @@ describe("Basic UI", () => {
it("should not have any accessibility violations", async () => {
const { queryByText, getByTestId, container } = setup(
-
+ ,
);
expect(queryByText(/Tree 1/)).not.toBeInTheDocument();
@@ -98,7 +98,7 @@ describe("Basic UI", () => {
describe("validation and error handling", () => {
it("shows all fields are required", async () => {
const { getByTestId, user, queryByRole, getAllByTestId } = setup(
-
+ ,
);
const map = getByTestId("map-and-label-map");
@@ -172,7 +172,7 @@ describe("validation and error handling", () => {
// ??
it("an error state is applied to a tabpanel button, when it's associated feature is invalid", async () => {
const { getByTestId, user, queryByRole } = setup(
-
+ ,
);
const map = getByTestId("map-and-label-map");
@@ -194,7 +194,7 @@ describe("validation and error handling", () => {
it("does not trigger handleSubmit when errors exist", async () => {
const handleSubmit = vi.fn();
const { getByTestId, user } = setup(
-
+ ,
);
const map = getByTestId("map-and-label-map");
@@ -497,11 +497,11 @@ describe("payload generation", () => {
test.todo("a submitted payload contains a GeoJSON feature collection");
// check payload contains GeoJSON feature collection
test.todo(
- "the feature collection contains all geospatial data inputted by the user"
+ "the feature collection contains all geospatial data inputted by the user",
);
// feature collection matches the mocked data
test.todo(
- "each feature's properties correspond with the details entered for that feature"
+ "each feature's properties correspond with the details entered for that feature",
);
// feature properties contain the answers to inputs
});
diff --git a/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts b/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts
index 1873246808..0b2424e603 100644
--- a/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts
+++ b/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts
@@ -11,7 +11,7 @@ import { mockTreeData } from "./mocks/GenericValues";
*/
export const addFeaturesToMap = async (
map: HTMLElement,
- features: Feature[]
+ features: Feature[],
) => {
const mockEvent = new CustomEvent("geojsonChange", {
detail: {
@@ -22,7 +22,7 @@ export const addFeaturesToMap = async (
};
export const addMultipleFeatures = (
- featureArray: Feature[]
+ featureArray: Feature[],
) => {
const map = screen.getByTestId("map-and-label-map");
const pointsAddedArray: Feature[] = [];
diff --git a/editor.planx.uk/src/components/RouteLoadingIndicator.tsx b/editor.planx.uk/src/components/RouteLoadingIndicator.tsx
index 72c6852ce2..4417471a18 100644
--- a/editor.planx.uk/src/components/RouteLoadingIndicator.tsx
+++ b/editor.planx.uk/src/components/RouteLoadingIndicator.tsx
@@ -33,4 +33,4 @@ const RouteLoadingIndicator: React.FC<{
);
};
-export default RouteLoadingIndicator;
\ No newline at end of file
+export default RouteLoadingIndicator;
diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx
index 1ae158e124..e6b0535e30 100644
--- a/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx
+++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/TeamMembers.tsx
@@ -16,7 +16,7 @@ import { TeamMember } from "./types";
export const TeamMembers = () => {
const [teamMembers, teamSlug] = useStore((state) => [
- state.teamMembers,
+ state.teamMembers,
state.teamSlug,
]);
@@ -48,7 +48,11 @@ export const TeamMembers = () => {
Editors have access to edit your services.
-
+
@@ -57,7 +61,10 @@ export const TeamMembers = () => {
Admins have editor access across all teams.
-
+
{archivedMembers.length > 0 && (
diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx
index 1c9a54c6a6..c82b41cf71 100644
--- a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx
+++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.addNewEditor.test.tsx
@@ -94,14 +94,18 @@ describe("when the addNewEditor modal is rendered", () => {
});
describe("'add a new editor' button is hidden from Templates team", () => {
- beforeEach(async() => {
- useStore.setState({ teamMembers: mockTeamMembersData, teamSlug: "templates" });
+ beforeEach(async () => {
+ useStore.setState({
+ teamMembers: mockTeamMembersData,
+ teamSlug: "templates",
+ });
});
it("hides the button on the Templates team", async () => {
const { user: _user } = await setupTeamMembersScreen();
const teamEditorsTable = screen.getByTestId("team-editors");
- const addEditorButton = within(teamEditorsTable).queryByText("Add a new editor");
+ const addEditorButton =
+ within(teamEditorsTable).queryByText("Add a new editor");
expect(addEditorButton).not.toBeInTheDocument();
});
});
diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.updateEditor.test.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.updateEditor.test.tsx
index 7cba480610..7527470705 100644
--- a/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.updateEditor.test.tsx
+++ b/editor.planx.uk/src/pages/FlowEditor/components/Team/tests/TeamMembers.updateEditor.test.tsx
@@ -24,7 +24,7 @@ describe("when a user presses 'edit button'", () => {
const teamEditorsTable = screen.getByTestId("team-editors");
const addEditorButton = await within(teamEditorsTable).findByTestId(
- "edit-button-0"
+ "edit-button-0",
);
user.click(addEditorButton);
@@ -64,7 +64,7 @@ describe("when a user deletes an input value", () => {
const teamEditorsTable = screen.getByTestId("team-editors");
const addEditorButton = await within(teamEditorsTable).findByTestId(
- "edit-button-0"
+ "edit-button-0",
);
await user.click(addEditorButton);
@@ -98,7 +98,7 @@ describe("when a user updates a field correctly", () => {
const teamEditorsTable = screen.getByTestId("team-editors");
const addEditorButton = await within(teamEditorsTable).findByTestId(
- "edit-button-0"
+ "edit-button-0",
);
await user.click(addEditorButton);
@@ -112,7 +112,7 @@ describe("when a user updates a field correctly", () => {
it("updates the field", async () => {
const firstNameInput = await screen.findByLabelText("First name");
expect(firstNameInput).toHaveDisplayValue(
- mockTeamMembersData[1].firstName + "bo"
+ mockTeamMembersData[1].firstName + "bo",
);
});
it("enables the update user button", async () => {
@@ -130,7 +130,7 @@ describe("when a user correctly updates an Editor", () => {
const teamEditorsTable = screen.getByTestId("team-editors");
const addEditorButton = await within(teamEditorsTable).findByTestId(
- "edit-button-0"
+ "edit-button-0",
);
await user.click(addEditorButton);
@@ -150,7 +150,7 @@ describe("when a user correctly updates an Editor", () => {
expect(within(membersTable).getByText(/Billbo/)).toBeInTheDocument();
});
expect(
- await screen.findByText(/Successfully updated a user/)
+ await screen.findByText(/Successfully updated a user/),
).toBeInTheDocument();
});
it("closes the modal", async () => {
@@ -160,14 +160,18 @@ describe("when a user correctly updates an Editor", () => {
});
it("shows a success message", async () => {
expect(
- await screen.findByText(/Successfully updated a user/)
+ await screen.findByText(/Successfully updated a user/),
).toBeInTheDocument();
});
});
describe("'edit' button is hidden from Templates team", () => {
- beforeEach(async() => {
- useStore.setState({ teamMembers: mockTeamMembersData, user: mockPlatformAdminUser, teamSlug: "templates" });
+ beforeEach(async () => {
+ useStore.setState({
+ teamMembers: mockTeamMembersData,
+ user: mockPlatformAdminUser,
+ teamSlug: "templates",
+ });
});
it("hides the button on the Templates team", async () => {
diff --git a/editor.planx.uk/src/pages/FlowEditor/index.tsx b/editor.planx.uk/src/pages/FlowEditor/index.tsx
index 4dd0e5a36c..9e580d5800 100644
--- a/editor.planx.uk/src/pages/FlowEditor/index.tsx
+++ b/editor.planx.uk/src/pages/FlowEditor/index.tsx
@@ -20,7 +20,8 @@ const EditorContainer = styled(Box)(() => ({
}));
const FlowEditor = () => {
- const [ flow, ...breadcrumbs ] = useCurrentRoute().url.pathname.split("/").at(-1)?.split(",") || [];
+ const [flow, ...breadcrumbs] =
+ useCurrentRoute().url.pathname.split("/").at(-1)?.split(",") || [];
const scrollContainerRef = useRef(null);
useScrollControlsAndRememberPosition(scrollContainerRef);
diff --git a/editor.planx.uk/src/routes/team.tsx b/editor.planx.uk/src/routes/team.tsx
index 02e14e96b4..864d158a59 100644
--- a/editor.planx.uk/src/routes/team.tsx
+++ b/editor.planx.uk/src/routes/team.tsx
@@ -85,7 +85,9 @@ const routes = compose(
"/:flow/service": setFlowAndLazyLoad(() => import("./serviceSettings")),
- "/:flow/submissions-log": setFlowAndLazyLoad(() => import("./submissionsLog")),
+ "/:flow/submissions-log": setFlowAndLazyLoad(
+ () => import("./submissionsLog"),
+ ),
"/members": lazy(() => import("./teamMembers")),
"/design": compose(