From 2796feae669e18c98751c29cbdc1d82f71f64e0d Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Wed, 11 Sep 2024 14:55:21 +0100 Subject: [PATCH 1/9] filloutform fn add --- .../MapAndLabel/Public/index.test.tsx | 67 +++++++++++++++---- .../components/MapAndLabel/test/utils.ts | 21 +++++- 2 files changed, 72 insertions(+), 16 deletions(-) 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 ee15ba20a9..c3d7e5a485 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 @@ -8,7 +8,11 @@ import { axe } from "vitest-axe"; import { point1, point2 } from "../test/mocks/geojson"; import { props } from "../test/mocks/Trees"; -import { addFeaturesToMap, addMultipleFeatures } from "../test/utils"; +import { + addFeaturesToMap, + addMultipleFeatures, + fillOutForm, +} from "../test/utils"; beforeAll(() => { if (!window.customElements.get("my-map")) { @@ -46,14 +50,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(); @@ -68,7 +72,7 @@ describe("Basic UI", () => { it("should not have any accessibility violations", async () => { const { queryByText, getByTestId, container } = setup( - , + ); expect(queryByText(/Tree 1/)).not.toBeInTheDocument(); @@ -86,7 +90,7 @@ describe("Basic UI", () => { describe("validation and error handling", () => { it("shows all fields are required", async () => { const { getAllByTestId, getByTestId, getByRole, user } = setup( - , + ); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); @@ -112,7 +116,7 @@ describe("validation and error handling", () => { // it shows all fields are required in a tab it("should show all fields are required, for all feature tabs", async () => { const { getByTestId, getByRole, user, debug } = setup( - , + ); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); @@ -183,7 +187,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, getByRole, user, getAllByTestId } = setup( - , + ); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); @@ -214,9 +218,46 @@ describe("validation and error handling", () => { test.todo("an error displays if the maximum number of items is exceeded"); describe("basic interactions - happy path", () => { - test.todo("adding an item to the map adds a feature tab"); + it("adding an item to the map adds a feature tab", async () => { + const { getByTestId, getByRole } = setup(); + const map = getByTestId("map-and-label-map"); + expect(map).toBeInTheDocument(); + + addFeaturesToMap(map, [point1]); + + expect(getByRole("tab", { name: /Tree 1/ })).toBeInTheDocument(); + + const firstTabPanel = getByTestId("vertical-tabpanel-0"); + + expect(firstTabPanel).toBeVisible(); + }); // add feature, see a tab (one feature only) - test.todo("a user can input details on a single feature and submit"); + it.only("a user can input details on a single feature and submit", async () => { + const { getAllByTestId, getByTestId, getByRole, user, debug } = setup( + + ); + const map = getByTestId("map-and-label-map"); + expect(map).toBeInTheDocument(); + + addFeaturesToMap(map, [point1]); + + const firstTabPanel = getByTestId("vertical-tabpanel-0"); + + expect(firstTabPanel).toBeVisible(); + + await fillOutForm(user); + + const continueButton = getByRole("button", { name: /Continue/ }); + expect(continueButton).toBeInTheDocument(); + + const errorMessages = getAllByTestId(/error-message-input/); + + await user.click(continueButton); + + errorMessages.forEach((message) => { + expect(message.textContent).toBeFalsy(); + }); + }); // only one feature, fill out form, submit test.todo("adding multiple features to the map adds multiple feature tabs"); // add more than one feature, see multiple tabs @@ -232,7 +273,7 @@ describe("copy feature select", () => { it.todo("is enabled once multiple features are present"); // copy select enabled once you add more features it.todo( - "lists all other features as options (the current feature is not listed)", + "lists all other features as options (the current feature is not listed)" ); // current tree is not an option in the copy select it.todo("copies all data from one feature to another"); @@ -254,11 +295,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 9baaeea2d1..7899289730 100644 --- a/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts +++ b/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts @@ -1,6 +1,8 @@ -import { screen } from "@testing-library/react"; +import { screen, within } from "@testing-library/react"; import { Feature, Point, Polygon } from "geojson"; import { act } from "react-dom/test-utils"; +import { mockTreeData } from "./mocks/GenericValues"; +import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup"; /** * Helper to mock a user's interaction with the @opensystemslab/map element @@ -8,7 +10,7 @@ import { act } from "react-dom/test-utils"; */ export const addFeaturesToMap = async ( map: HTMLElement, - features: Feature[], + features: Feature[] ) => { const mockEvent = new CustomEvent("geojsonChange", { detail: { @@ -19,7 +21,7 @@ export const addFeaturesToMap = async ( }; export const addMultipleFeatures = ( - featureArray: Feature[], + featureArray: Feature[] ) => { const map = screen.getByTestId("map-and-label-map"); const pointsAddedArray: Feature[] = []; @@ -28,3 +30,16 @@ export const addMultipleFeatures = ( addFeaturesToMap(map, pointsAddedArray); }); }; + +export const fillOutForm = async (user: UserEvent) => { + const speciesInput = screen.getByLabelText("Species"); + await user.type(speciesInput, mockTreeData.species); + const workInput = screen.getByLabelText("Proposed work"); + await user.type(workInput, mockTreeData.work); + const justificationInput = screen.getByLabelText("Justification"); + await user.type(justificationInput, mockTreeData.justification); + const urgencyDiv = screen.getByTitle("Urgency"); + const urgencySelect = within(urgencyDiv).getByRole("combobox"); + await user.click(urgencySelect); + await user.click(screen.getByRole("option", { name: /low/i })); +}; From e970c68c2eb49dd355005449b773b26f48282348 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Mon, 16 Sep 2024 18:30:23 +0100 Subject: [PATCH 2/9] happy path - multi tab work --- .../MapAndLabel/Public/index.test.tsx | 137 +++++++++++++++--- 1 file changed, 117 insertions(+), 20 deletions(-) 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 c3d7e5a485..1a436eeac8 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 @@ -1,12 +1,14 @@ import { MyMap } from "@opensystemslab/map"; import { Presentational as MapAndLabel } from "@planx/components/MapAndLabel/Public"; import { waitFor, within } from "@testing-library/react"; +import { exp } from "mathjs"; import React from "react"; import { setup } from "testUtils"; import { vi } from "vitest"; import { axe } from "vitest-axe"; -import { point1, point2 } from "../test/mocks/geojson"; +import { mockTreeData } from "../test/mocks/GenericValues"; +import { point1, point2, point3 } from "../test/mocks/geojson"; import { props } from "../test/mocks/Trees"; import { addFeaturesToMap, @@ -50,14 +52,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(); @@ -72,7 +74,7 @@ describe("Basic UI", () => { it("should not have any accessibility violations", async () => { const { queryByText, getByTestId, container } = setup( - + , ); expect(queryByText(/Tree 1/)).not.toBeInTheDocument(); @@ -90,7 +92,7 @@ describe("Basic UI", () => { describe("validation and error handling", () => { it("shows all fields are required", async () => { const { getAllByTestId, getByTestId, getByRole, user } = setup( - + , ); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); @@ -115,12 +117,9 @@ describe("validation and error handling", () => { // it shows all fields are required in a tab it("should show all fields are required, for all feature tabs", async () => { - const { getByTestId, getByRole, user, debug } = setup( - - ); + const { getByTestId, getByRole, user } = setup(); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); - debug(); addMultipleFeatures([point1, point2]); @@ -187,7 +186,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, getByRole, user, getAllByTestId } = setup( - + , ); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); @@ -232,10 +231,11 @@ describe("basic interactions - happy path", () => { expect(firstTabPanel).toBeVisible(); }); // add feature, see a tab (one feature only) - it.only("a user can input details on a single feature and submit", async () => { + it("a user can input details on a single feature and submit", async () => { const { getAllByTestId, getByTestId, getByRole, user, debug } = setup( - + , ); + const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); @@ -259,12 +259,109 @@ describe("basic interactions - happy path", () => { }); }); // only one feature, fill out form, submit - test.todo("adding multiple features to the map adds multiple feature tabs"); + it("adding multiple features to the map adds multiple feature tabs", async () => { + const { getByTestId, getByRole, user, getByLabelText, getAllByTestId } = + setup(); + const map = getByTestId("map-and-label-map"); + expect(map).toBeInTheDocument(); + + addMultipleFeatures([point1, point2, point3]); + + // vertical side tab query + const firstTab = getByRole("tab", { name: /Tree 1/ }); + const secondTab = getByRole("tab", { name: /Tree 2/ }); + const thirdTab = getByRole("tab", { name: /Tree 3/ }); + + expect(firstTab).toBeInTheDocument(); + expect(secondTab).toBeInTheDocument(); + expect(thirdTab).toBeInTheDocument(); + + expect(thirdTab).toHaveAttribute("aria-selected", "true"); + }); // add more than one feature, see multiple tabs - test.todo("a user can input details on multiple features and submit"); + it("a user can input details on multiple features and submit", async () => { + const { getByTestId, getByRole, user, getAllByTestId } = setup( + , + ); + const map = getByTestId("map-and-label-map"); + expect(map).toBeInTheDocument(); + + addMultipleFeatures([point1, point2]); + + // vertical side tab query + const firstTab = getByRole("tab", { name: /Tree 1/ }); + const firstTabPanel = getByTestId("vertical-tabpanel-0"); + const secondTabPanel = getByTestId("vertical-tabpanel-1"); + + await fillOutForm(user); + const secondSpeciesInput = within(secondTabPanel).getByLabelText("Species"); + + expect(secondSpeciesInput).toHaveDisplayValue("Larch"); + + await user.click(firstTab); + + // check form on screen is reset + const firstSpeciesInput = within(firstTabPanel).getByLabelText("Species"); + expect(secondSpeciesInput).not.toBeInTheDocument(); + expect(firstSpeciesInput).not.toHaveDisplayValue("Larch"); + + await fillOutForm(user); + + const continueButton = getByRole("button", { name: /Continue/ }); + expect(continueButton).toBeInTheDocument(); + + const errorMessages = getAllByTestId(/error-message-input/); + + await user.click(continueButton); + + errorMessages.forEach((message) => { + expect(message.textContent).toBeFalsy(); + }); + }); // add details to more than one tab, submit - test.todo("a user can input details on feature tabs in any order"); - // ?? + it("a user can input details on feature tabs in any order", async () => { + const { getByTestId, getByRole, user, getByLabelText, getByTitle } = setup( + , + ); + const map = getByTestId("map-and-label-map"); + expect(map).toBeInTheDocument(); + + addMultipleFeatures([point1, point2, point3]); + + // vertical side tab query + const firstTab = getByRole("tab", { name: /Tree 1/ }); + const secondTab = getByRole("tab", { name: /Tree 2/ }); + + const firstTabPanel = getByTestId("vertical-tabpanel-0"); + const secondTabPanel = getByTestId("vertical-tabpanel-1"); + + await user.click(firstTab); + + const firstSpeciesInput = within(firstTabPanel).getByLabelText("Species"); + expect(firstSpeciesInput).not.toHaveDisplayValue("Larch"); + + await user.type(firstSpeciesInput, mockTreeData.species); + const firstWorkInput = getByLabelText("Proposed work"); + await user.type(firstWorkInput, mockTreeData.work); + + await user.click(secondTab); + + const secondSpeciesInput = within(secondTabPanel).getByLabelText("Species"); + expect(secondSpeciesInput).not.toHaveDisplayValue("Larch"); + await user.type(secondSpeciesInput, mockTreeData.species); + const secondWorkInput = getByLabelText("Proposed work"); + await user.type(secondWorkInput, mockTreeData.work); + + await user.click(firstTab); + + expect(firstSpeciesInput).toHaveDisplayValue("Larch"); + const justificationInput = getByLabelText("Justification"); + await user.type(justificationInput, mockTreeData.justification); + const urgencyDiv = getByTitle("Urgency"); + const urgencySelect = within(urgencyDiv).getByRole("combobox"); + await user.click(urgencySelect); + await user.click(getByRole("option", { name: /low/i })); + }); }); describe("copy feature select", () => { @@ -273,7 +370,7 @@ describe("copy feature select", () => { it.todo("is enabled once multiple features are present"); // copy select enabled once you add more features it.todo( - "lists all other features as options (the current feature is not listed)" + "lists all other features as options (the current feature is not listed)", ); // current tree is not an option in the copy select it.todo("copies all data from one feature to another"); @@ -295,11 +392,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 }); From 5a31807798105007ed8ea7491e217f91e5ad5819 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 10:25:57 +0100 Subject: [PATCH 3/9] finish happy path to dos --- .../MapAndLabel/Public/index.test.tsx | 60 ++++++++++++++----- 1 file changed, 45 insertions(+), 15 deletions(-) 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 1a436eeac8..47b942dd7e 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 @@ -320,15 +320,19 @@ describe("basic interactions - happy path", () => { }); // add details to more than one tab, submit it("a user can input details on feature tabs in any order", async () => { - const { getByTestId, getByRole, user, getByLabelText, getByTitle } = setup( - , - ); + const { + getByTestId, + getByRole, + user, + getByLabelText, + getByTitle, + getAllByTestId, + } = setup(); const map = getByTestId("map-and-label-map"); expect(map).toBeInTheDocument(); - addMultipleFeatures([point1, point2, point3]); + addMultipleFeatures([point1, point2]); - // vertical side tab query const firstTab = getByRole("tab", { name: /Tree 1/ }); const secondTab = getByRole("tab", { name: /Tree 2/ }); @@ -340,27 +344,53 @@ describe("basic interactions - happy path", () => { const firstSpeciesInput = within(firstTabPanel).getByLabelText("Species"); expect(firstSpeciesInput).not.toHaveDisplayValue("Larch"); - await user.type(firstSpeciesInput, mockTreeData.species); + // partially fill out firstTabPanel + await user.type(firstSpeciesInput, "Larch"); const firstWorkInput = getByLabelText("Proposed work"); - await user.type(firstWorkInput, mockTreeData.work); + await user.type(firstWorkInput, "Chopping it down"); await user.click(secondTab); + // partially fill out secondTabPanel const secondSpeciesInput = within(secondTabPanel).getByLabelText("Species"); expect(secondSpeciesInput).not.toHaveDisplayValue("Larch"); - await user.type(secondSpeciesInput, mockTreeData.species); + await user.type(secondSpeciesInput, "Larch"); const secondWorkInput = getByLabelText("Proposed work"); - await user.type(secondWorkInput, mockTreeData.work); + await user.type(secondWorkInput, "Chopping it down"); await user.click(firstTab); - + // check that the data stays within the firstTabPanel expect(firstSpeciesInput).toHaveDisplayValue("Larch"); - const justificationInput = getByLabelText("Justification"); - await user.type(justificationInput, mockTreeData.justification); - const urgencyDiv = getByTitle("Urgency"); - const urgencySelect = within(urgencyDiv).getByRole("combobox"); - await user.click(urgencySelect); + // Complete the filling out of the firstTabPanel + const firstJustificationInput = getByLabelText("Justification"); + await user.type(firstJustificationInput, "Cause I can"); + const firstUrgencyDiv = getByTitle("Urgency"); + const firstUrgencySelect = within(firstUrgencyDiv).getByRole("combobox"); + await user.click(firstUrgencySelect); + await user.click(getByRole("option", { name: /low/i })); + + await user.click(secondTab); + + // check that the data stays within the secondTabPanel + expect(secondSpeciesInput).toHaveDisplayValue("Larch"); + // Complete the filling out of the secondTabPanel + const secondJustificationInput = getByLabelText("Justification"); + await user.type(secondJustificationInput, "Cause I can"); + const secondUrgencyDiv = getByTitle("Urgency"); + const secondUrgencySelect = within(secondUrgencyDiv).getByRole("combobox"); + await user.click(secondUrgencySelect); await user.click(getByRole("option", { name: /low/i })); + + const continueButton = getByRole("button", { name: /Continue/ }); + expect(continueButton).toBeInTheDocument(); + + const errorMessages = getAllByTestId(/error-message-input/); + + await user.click(continueButton); + + errorMessages.forEach((message) => { + expect(message.textContent).toBeFalsy(); + }); }); }); From eb65755de1764208b1582d6ba0ed60b1dde7fcc0 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 10:55:29 +0100 Subject: [PATCH 4/9] remove redundant toBeInDocument() --- .../MapAndLabel/Public/index.test.tsx | 57 +++++++------------ 1 file changed, 19 insertions(+), 38 deletions(-) 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 47b942dd7e..112530b4e8 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 @@ -7,7 +7,6 @@ import { setup } from "testUtils"; import { vi } from "vitest"; import { axe } from "vitest-axe"; -import { mockTreeData } from "../test/mocks/GenericValues"; import { point1, point2, point3 } from "../test/mocks/geojson"; import { props } from "../test/mocks/Trees"; import { @@ -46,7 +45,6 @@ describe("Basic UI", () => { it("removes the prompt once a feature is added", async () => { const { queryByText, getByTestId } = setup(); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); @@ -64,7 +62,6 @@ describe("Basic UI", () => { expect(queryByText(/Tree 1/)).not.toBeInTheDocument(); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); @@ -79,7 +76,6 @@ describe("Basic UI", () => { expect(queryByText(/Tree 1/)).not.toBeInTheDocument(); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); @@ -95,14 +91,13 @@ describe("validation and error handling", () => { , ); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); - expect(getByRole("tab", { name: /Tree 1/ })).toBeInTheDocument(); + getByRole("tab", { name: /Tree 1/ }); const continueButton = getByRole("button", { name: /Continue/ }); - expect(continueButton).toBeInTheDocument(); + await user.click(continueButton); const errorMessages = getAllByTestId(/error-message-input/); @@ -118,24 +113,18 @@ describe("validation and error handling", () => { // it shows all fields are required in a tab it("should show all fields are required, for all feature tabs", async () => { const { getByTestId, getByRole, user } = setup(); - const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); + getByTestId("map-and-label-map"); addMultipleFeatures([point1, point2]); // vertical side tab query const firstTab = getByRole("tab", { name: /Tree 1/ }); - const secondTab = getByRole("tab", { name: /Tree 2/ }); - - // side tab validation - expect(firstTab).toBeInTheDocument(); - expect(secondTab).toBeInTheDocument(); // form for each tab const firstTabPanel = getByTestId("vertical-tabpanel-0"); const secondTabPanel = getByTestId("vertical-tabpanel-1"); - // default is to start on seond tab panel since we add two points + // default is to start on second tab panel since we add two points expect(firstTabPanel).not.toBeVisible(); expect(secondTabPanel).toBeVisible(); @@ -170,8 +159,7 @@ describe("validation and error handling", () => { // it shows all fields are required across different tabs it("should show an error if the minimum number of items is not met", async () => { const { getByTestId, getByRole, user } = setup(); - const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); + getByTestId("map-and-label-map"); const continueButton = getByRole("button", { name: /Continue/ }); @@ -180,25 +168,23 @@ describe("validation and error handling", () => { const errorWrapper = getByTestId(/error-wrapper/); const errorMessage = within(errorWrapper).getByText(/You must plot /); - - expect(errorMessage).toBeInTheDocument(); + expect(errorMessage).toBeVisible(); }); // ?? it("an error state is applied to a tabpanel button, when it's associated feature is invalid", async () => { - const { getByTestId, getByRole, user, getAllByTestId } = setup( + const { getByTestId, getByRole, user, getAllByTestId, queryByRole } = setup( , ); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); - const tabOne = getByRole("tab", { name: /Tree 1/ }); + const tabOne = queryByRole("tab", { name: /Tree 1/ }); expect(tabOne).toBeInTheDocument(); const continueButton = getByRole("button", { name: /Continue/ }); - expect(continueButton).toBeInTheDocument(); + await user.click(continueButton); const errorMessages = getAllByTestId(/error-message-input/); @@ -220,11 +206,10 @@ describe("basic interactions - happy path", () => { it("adding an item to the map adds a feature tab", async () => { const { getByTestId, getByRole } = setup(); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); - expect(getByRole("tab", { name: /Tree 1/ })).toBeInTheDocument(); + getByRole("tab", { name: /Tree 1/ }); const firstTabPanel = getByTestId("vertical-tabpanel-0"); @@ -232,12 +217,11 @@ describe("basic interactions - happy path", () => { }); // add feature, see a tab (one feature only) it("a user can input details on a single feature and submit", async () => { - const { getAllByTestId, getByTestId, getByRole, user, debug } = setup( + const { getAllByTestId, getByTestId, getByRole, user } = setup( , ); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addFeaturesToMap(map, [point1]); @@ -248,7 +232,6 @@ describe("basic interactions - happy path", () => { await fillOutForm(user); const continueButton = getByRole("button", { name: /Continue/ }); - expect(continueButton).toBeInTheDocument(); const errorMessages = getAllByTestId(/error-message-input/); @@ -260,23 +243,25 @@ describe("basic interactions - happy path", () => { }); // only one feature, fill out form, submit it("adding multiple features to the map adds multiple feature tabs", async () => { - const { getByTestId, getByRole, user, getByLabelText, getAllByTestId } = - setup(); + const { getByTestId, queryByRole } = setup(); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addMultipleFeatures([point1, point2, point3]); // vertical side tab query - const firstTab = getByRole("tab", { name: /Tree 1/ }); - const secondTab = getByRole("tab", { name: /Tree 2/ }); - const thirdTab = getByRole("tab", { name: /Tree 3/ }); + const firstTab = queryByRole("tab", { name: /Tree 1/ }); + const secondTab = queryByRole("tab", { name: /Tree 2/ }); + const thirdTab = queryByRole("tab", { name: /Tree 3/ }); + const fourthTab = queryByRole("tab", { name: /Tree 4/ }); expect(firstTab).toBeInTheDocument(); expect(secondTab).toBeInTheDocument(); expect(thirdTab).toBeInTheDocument(); + expect(fourthTab).not.toBeInTheDocument(); expect(thirdTab).toHaveAttribute("aria-selected", "true"); + expect(secondTab).toHaveAttribute("aria-selected", "false"); + expect(firstTab).toHaveAttribute("aria-selected", "false"); }); // add more than one feature, see multiple tabs it("a user can input details on multiple features and submit", async () => { @@ -284,7 +269,6 @@ describe("basic interactions - happy path", () => { , ); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addMultipleFeatures([point1, point2]); @@ -308,7 +292,6 @@ describe("basic interactions - happy path", () => { await fillOutForm(user); const continueButton = getByRole("button", { name: /Continue/ }); - expect(continueButton).toBeInTheDocument(); const errorMessages = getAllByTestId(/error-message-input/); @@ -329,7 +312,6 @@ describe("basic interactions - happy path", () => { getAllByTestId, } = setup(); const map = getByTestId("map-and-label-map"); - expect(map).toBeInTheDocument(); addMultipleFeatures([point1, point2]); @@ -382,7 +364,6 @@ describe("basic interactions - happy path", () => { await user.click(getByRole("option", { name: /low/i })); const continueButton = getByRole("button", { name: /Continue/ }); - expect(continueButton).toBeInTheDocument(); const errorMessages = getAllByTestId(/error-message-input/); From 218b11a6c5f4d3efe459e4426e3eacc89d8a5c32 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 11:01:48 +0100 Subject: [PATCH 5/9] add partial fill out form fn --- .../MapAndLabel/Public/index.test.tsx | 43 ++++++------------- .../components/MapAndLabel/test/utils.ts | 23 ++++++++-- 2 files changed, 34 insertions(+), 32 deletions(-) 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 112530b4e8..e3ff6b133e 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 @@ -1,7 +1,6 @@ import { MyMap } from "@opensystemslab/map"; import { Presentational as MapAndLabel } from "@planx/components/MapAndLabel/Public"; import { waitFor, within } from "@testing-library/react"; -import { exp } from "mathjs"; import React from "react"; import { setup } from "testUtils"; import { vi } from "vitest"; @@ -12,7 +11,9 @@ import { props } from "../test/mocks/Trees"; import { addFeaturesToMap, addMultipleFeatures, + fillOutFirstHalfOfForm, fillOutForm, + fillOutSecondHalfOfForm, } from "../test/utils"; beforeAll(() => { @@ -303,14 +304,9 @@ describe("basic interactions - happy path", () => { }); // add details to more than one tab, submit it("a user can input details on feature tabs in any order", async () => { - const { - getByTestId, - getByRole, - user, - getByLabelText, - getByTitle, - getAllByTestId, - } = setup(); + const { getByTestId, getByRole, user, getAllByTestId } = setup( + , + ); const map = getByTestId("map-and-label-map"); addMultipleFeatures([point1, point2]); @@ -327,41 +323,30 @@ describe("basic interactions - happy path", () => { expect(firstSpeciesInput).not.toHaveDisplayValue("Larch"); // partially fill out firstTabPanel - await user.type(firstSpeciesInput, "Larch"); - const firstWorkInput = getByLabelText("Proposed work"); - await user.type(firstWorkInput, "Chopping it down"); + await fillOutFirstHalfOfForm(user); await user.click(secondTab); - - // partially fill out secondTabPanel const secondSpeciesInput = within(secondTabPanel).getByLabelText("Species"); expect(secondSpeciesInput).not.toHaveDisplayValue("Larch"); - await user.type(secondSpeciesInput, "Larch"); - const secondWorkInput = getByLabelText("Proposed work"); - await user.type(secondWorkInput, "Chopping it down"); + + // partially fill out secondTabPanel + await fillOutFirstHalfOfForm(user); await user.click(firstTab); + // check that the data stays within the firstTabPanel expect(firstSpeciesInput).toHaveDisplayValue("Larch"); + // Complete the filling out of the firstTabPanel - const firstJustificationInput = getByLabelText("Justification"); - await user.type(firstJustificationInput, "Cause I can"); - const firstUrgencyDiv = getByTitle("Urgency"); - const firstUrgencySelect = within(firstUrgencyDiv).getByRole("combobox"); - await user.click(firstUrgencySelect); - await user.click(getByRole("option", { name: /low/i })); + await fillOutSecondHalfOfForm(user); await user.click(secondTab); // check that the data stays within the secondTabPanel expect(secondSpeciesInput).toHaveDisplayValue("Larch"); + // Complete the filling out of the secondTabPanel - const secondJustificationInput = getByLabelText("Justification"); - await user.type(secondJustificationInput, "Cause I can"); - const secondUrgencyDiv = getByTitle("Urgency"); - const secondUrgencySelect = within(secondUrgencyDiv).getByRole("combobox"); - await user.click(secondUrgencySelect); - await user.click(getByRole("option", { name: /low/i })); + await fillOutSecondHalfOfForm(user); const continueButton = getByRole("button", { name: /Continue/ }); 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 7899289730..1a99f7da0d 100644 --- a/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts +++ b/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts @@ -1,8 +1,9 @@ import { screen, within } from "@testing-library/react"; +import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup"; import { Feature, Point, Polygon } from "geojson"; import { act } from "react-dom/test-utils"; + import { mockTreeData } from "./mocks/GenericValues"; -import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup"; /** * Helper to mock a user's interaction with the @opensystemslab/map element @@ -10,7 +11,7 @@ import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup"; */ export const addFeaturesToMap = async ( map: HTMLElement, - features: Feature[] + features: Feature[], ) => { const mockEvent = new CustomEvent("geojsonChange", { detail: { @@ -21,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[] = []; @@ -43,3 +44,19 @@ export const fillOutForm = async (user: UserEvent) => { await user.click(urgencySelect); await user.click(screen.getByRole("option", { name: /low/i })); }; + +export const fillOutFirstHalfOfForm = async (user: UserEvent) => { + const speciesInput = screen.getByLabelText("Species"); + await user.type(speciesInput, mockTreeData.species); + const workInput = screen.getByLabelText("Proposed work"); + await user.type(workInput, mockTreeData.work); +}; + +export const fillOutSecondHalfOfForm = async (user: UserEvent) => { + const justificationInput = screen.getByLabelText("Justification"); + await user.type(justificationInput, mockTreeData.justification); + const urgencyDiv = screen.getByTitle("Urgency"); + const urgencySelect = within(urgencyDiv).getByRole("combobox"); + await user.click(urgencySelect); + await user.click(screen.getByRole("option", { name: /low/i })); +}; From 3ff76ad3833e5f8d0271dab25201448e9c09664d Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 11:13:48 +0100 Subject: [PATCH 6/9] refactor: add fn for error message checking --- .../MapAndLabel/Public/index.test.tsx | 93 +++++-------------- .../components/MapAndLabel/test/utils.ts | 23 +++++ 2 files changed, 46 insertions(+), 70 deletions(-) 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 e3ff6b133e..7b48b24f72 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 @@ -11,6 +11,9 @@ import { props } from "../test/mocks/Trees"; import { addFeaturesToMap, addMultipleFeatures, + checkErrorMessagesEmpty, + checkErrorMessagesPopulated, + clickContinue, fillOutFirstHalfOfForm, fillOutForm, fillOutSecondHalfOfForm, @@ -88,27 +91,19 @@ describe("Basic UI", () => { // Schema and field validation is handled in both List and Schema folders - here we're only testing the MapAndLabel specific error handling describe("validation and error handling", () => { it("shows all fields are required", async () => { - const { getAllByTestId, getByTestId, getByRole, user } = setup( + const { getByTestId, user, queryByRole } = setup( , ); const map = getByTestId("map-and-label-map"); addFeaturesToMap(map, [point1]); - getByRole("tab", { name: /Tree 1/ }); - - const continueButton = getByRole("button", { name: /Continue/ }); - - await user.click(continueButton); - - const errorMessages = getAllByTestId(/error-message-input/); + const tabOne = queryByRole("tab", { name: /Tree 1/ }); + expect(tabOne).toBeInTheDocument(); - // Date field has been removed so only 4 inputs - expect(errorMessages).toHaveLength(4); + await clickContinue(user); - errorMessages.forEach((message) => { - expect(message).not.toBeEmptyDOMElement(); - }); + await checkErrorMessagesPopulated(); }); // it shows all fields are required in a tab @@ -133,38 +128,25 @@ describe("validation and error handling", () => { expect(secondTabPanel.childElementCount).toBeGreaterThan(0); expect(firstTabPanel.childElementCount).toBe(0); - const continueButton = getByRole("button", { name: /Continue/ }); - await user.click(continueButton); + await clickContinue(user); // error messages appear - const errorMessagesTabTwo = - within(secondTabPanel).getAllByTestId(/error-message-input/); - expect(errorMessagesTabTwo).toHaveLength(4); - - // error messages are empty but visible before error state induced - // this ensures they contain the error message text - errorMessagesTabTwo.forEach((input) => { - expect(input).not.toBeEmptyDOMElement(); - }); + await checkErrorMessagesPopulated(); await user.click(firstTab); expect(firstTabPanel).toBeVisible(); // error messages persist - const errorMessagesTabOne = - within(firstTabPanel).getAllByTestId(/error-message-input/); - expect(errorMessagesTabOne).toHaveLength(4); + await checkErrorMessagesPopulated(); }); // it shows all fields are required across different tabs it("should show an error if the minimum number of items is not met", async () => { - const { getByTestId, getByRole, user } = setup(); + const { getByTestId, user } = setup(); getByTestId("map-and-label-map"); - const continueButton = getByRole("button", { name: /Continue/ }); - - await user.click(continueButton); + await clickContinue(user); const errorWrapper = getByTestId(/error-wrapper/); @@ -173,7 +155,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, getByRole, user, getAllByTestId, queryByRole } = setup( + const { getByTestId, user, queryByRole } = setup( , ); const map = getByTestId("map-and-label-map"); @@ -184,18 +166,9 @@ describe("validation and error handling", () => { expect(tabOne).toBeInTheDocument(); - const continueButton = getByRole("button", { name: /Continue/ }); - - await user.click(continueButton); + await clickContinue(user); - const errorMessages = getAllByTestId(/error-message-input/); - - // check error messages are correct amount and contain info - expect(errorMessages).toHaveLength(4); - - errorMessages.forEach((message) => { - expect(message).not.toBeEmptyDOMElement(); - }); + await checkErrorMessagesPopulated(); expect(tabOne).toHaveStyle("border-left: 5px solid #D4351C"); }); @@ -218,9 +191,7 @@ describe("basic interactions - happy path", () => { }); // add feature, see a tab (one feature only) it("a user can input details on a single feature and submit", async () => { - const { getAllByTestId, getByTestId, getByRole, user } = setup( - , - ); + const { getByTestId, user } = setup(); const map = getByTestId("map-and-label-map"); @@ -232,15 +203,9 @@ describe("basic interactions - happy path", () => { await fillOutForm(user); - const continueButton = getByRole("button", { name: /Continue/ }); - - const errorMessages = getAllByTestId(/error-message-input/); + await clickContinue(user); - await user.click(continueButton); - - errorMessages.forEach((message) => { - expect(message.textContent).toBeFalsy(); - }); + await checkErrorMessagesEmpty(); }); // only one feature, fill out form, submit it("adding multiple features to the map adds multiple feature tabs", async () => { @@ -292,15 +257,9 @@ describe("basic interactions - happy path", () => { await fillOutForm(user); - const continueButton = getByRole("button", { name: /Continue/ }); - - const errorMessages = getAllByTestId(/error-message-input/); - - await user.click(continueButton); + await clickContinue(user); - errorMessages.forEach((message) => { - expect(message.textContent).toBeFalsy(); - }); + await checkErrorMessagesEmpty(); }); // add details to more than one tab, submit it("a user can input details on feature tabs in any order", async () => { @@ -348,15 +307,9 @@ describe("basic interactions - happy path", () => { // Complete the filling out of the secondTabPanel await fillOutSecondHalfOfForm(user); - const continueButton = getByRole("button", { name: /Continue/ }); - - const errorMessages = getAllByTestId(/error-message-input/); - - await user.click(continueButton); + await clickContinue(user); - errorMessages.forEach((message) => { - expect(message.textContent).toBeFalsy(); - }); + await checkErrorMessagesEmpty(); }); }); 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 1a99f7da0d..1a8586d85c 100644 --- a/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts +++ b/editor.planx.uk/src/@planx/components/MapAndLabel/test/utils.ts @@ -60,3 +60,26 @@ export const fillOutSecondHalfOfForm = async (user: UserEvent) => { await user.click(urgencySelect); await user.click(screen.getByRole("option", { name: /low/i })); }; + +export const clickContinue = async (user: UserEvent) => { + const continueButton = screen.getByRole("button", { name: /Continue/ }); + await user.click(continueButton); +}; + +export const checkErrorMessagesEmpty = async () => { + const errorMessages = screen.getAllByTestId(/error-message-input/); + + errorMessages.forEach((message) => { + expect(message.textContent).toBeFalsy(); + }); +}; + +export const checkErrorMessagesPopulated = async () => { + const errorMessages = screen.getAllByTestId(/error-message-input/); + + expect(errorMessages).toHaveLength(4); + + errorMessages.forEach((message) => { + expect(message).not.toBeEmptyDOMElement(); + }); +}; From 4b6190aac600f31734ae5aa724180ac826ab662e Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 11:19:22 +0100 Subject: [PATCH 7/9] reduce refinement to keep explicit test pattern --- .../MapAndLabel/Public/index.test.tsx | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) 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 7b48b24f72..63ef582427 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 @@ -91,7 +91,7 @@ describe("Basic UI", () => { // Schema and field validation is handled in both List and Schema folders - here we're only testing the MapAndLabel specific error handling describe("validation and error handling", () => { it("shows all fields are required", async () => { - const { getByTestId, user, queryByRole } = setup( + const { getByTestId, user, queryByRole, getAllByTestId } = setup( , ); const map = getByTestId("map-and-label-map"); @@ -101,9 +101,21 @@ describe("validation and error handling", () => { const tabOne = queryByRole("tab", { name: /Tree 1/ }); expect(tabOne).toBeInTheDocument(); + const firstTabPanel = getByTestId("vertical-tabpanel-0"); + const firstSpeciesInput = within(firstTabPanel).getByLabelText("Species"); + + // check input is empty + expect(firstSpeciesInput).toHaveDisplayValue(""); + await clickContinue(user); - await checkErrorMessagesPopulated(); + const errorMessages = getAllByTestId(/error-message-input/); + + expect(errorMessages).toHaveLength(4); + + errorMessages.forEach((message) => { + expect(message).not.toBeEmptyDOMElement(); + }); }); // it shows all fields are required in a tab @@ -178,18 +190,16 @@ test.todo("an error displays if the maximum number of items is exceeded"); describe("basic interactions - happy path", () => { it("adding an item to the map adds a feature tab", async () => { - const { getByTestId, getByRole } = setup(); + const { getByTestId } = setup(); const map = getByTestId("map-and-label-map"); addFeaturesToMap(map, [point1]); - getByRole("tab", { name: /Tree 1/ }); - const firstTabPanel = getByTestId("vertical-tabpanel-0"); expect(firstTabPanel).toBeVisible(); }); - // add feature, see a tab (one feature only) + it("a user can input details on a single feature and submit", async () => { const { getByTestId, user } = setup(); @@ -207,7 +217,7 @@ describe("basic interactions - happy path", () => { await checkErrorMessagesEmpty(); }); - // only one feature, fill out form, submit + it("adding multiple features to the map adds multiple feature tabs", async () => { const { getByTestId, queryByRole } = setup(); const map = getByTestId("map-and-label-map"); @@ -220,6 +230,7 @@ describe("basic interactions - happy path", () => { const thirdTab = queryByRole("tab", { name: /Tree 3/ }); const fourthTab = queryByRole("tab", { name: /Tree 4/ }); + // check the right amount are in the document expect(firstTab).toBeInTheDocument(); expect(secondTab).toBeInTheDocument(); expect(thirdTab).toBeInTheDocument(); @@ -229,7 +240,7 @@ describe("basic interactions - happy path", () => { expect(secondTab).toHaveAttribute("aria-selected", "false"); expect(firstTab).toHaveAttribute("aria-selected", "false"); }); - // add more than one feature, see multiple tabs + it("a user can input details on multiple features and submit", async () => { const { getByTestId, getByRole, user, getAllByTestId } = setup( , @@ -263,9 +274,7 @@ describe("basic interactions - happy path", () => { }); // add details to more than one tab, submit it("a user can input details on feature tabs in any order", async () => { - const { getByTestId, getByRole, user, getAllByTestId } = setup( - , - ); + const { getByTestId, getByRole, user } = setup(); const map = getByTestId("map-and-label-map"); addMultipleFeatures([point1, point2]); From cc32099f392351de41fadcff6d3c520e9f916f5f Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 14:27:29 +0100 Subject: [PATCH 8/9] add handleSubmit check and add Daf's comments --- .../MapAndLabel/Public/index.test.tsx | 45 ++++++++++++------- .../components/MapAndLabel/test/utils.ts | 22 +++------ 2 files changed, 36 insertions(+), 31 deletions(-) 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 63ef582427..39a9b7dd87 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 @@ -54,14 +54,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(); @@ -75,7 +75,7 @@ describe("Basic UI", () => { it("should not have any accessibility violations", async () => { const { queryByText, getByTestId, container } = setup( - , + ); expect(queryByText(/Tree 1/)).not.toBeInTheDocument(); @@ -92,7 +92,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"); @@ -168,7 +168,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"); @@ -186,6 +186,22 @@ describe("validation and error handling", () => { }); // shows the error state on a tab when it's invalid }); + +it("does not trigger handleSubmit when errors exist", async () => { + const handleSubmit = vi.fn(); + const { getByTestId, user } = setup( + + ); + const map = getByTestId("map-and-label-map"); + + addFeaturesToMap(map, [point1]); + + await clickContinue(user); + + await checkErrorMessagesPopulated(); + + expect(handleSubmit).not.toBeCalled(); +}); test.todo("an error displays if the maximum number of items is exceeded"); describe("basic interactions - happy path", () => { @@ -236,16 +252,14 @@ describe("basic interactions - happy path", () => { expect(thirdTab).toBeInTheDocument(); expect(fourthTab).not.toBeInTheDocument(); - expect(thirdTab).toHaveAttribute("aria-selected", "true"); - expect(secondTab).toHaveAttribute("aria-selected", "false"); expect(firstTab).toHaveAttribute("aria-selected", "false"); + expect(secondTab).toHaveAttribute("aria-selected", "false"); + expect(thirdTab).toHaveAttribute("aria-selected", "true"); }); it("a user can input details on multiple features and submit", async () => { - const { getByTestId, getByRole, user, getAllByTestId } = setup( - , - ); - const map = getByTestId("map-and-label-map"); + const { getByTestId, getByRole, user } = setup(); + getByTestId("map-and-label-map"); addMultipleFeatures([point1, point2]); @@ -272,7 +286,6 @@ describe("basic interactions - happy path", () => { await checkErrorMessagesEmpty(); }); - // add details to more than one tab, submit it("a user can input details on feature tabs in any order", async () => { const { getByTestId, getByRole, user } = setup(); const map = getByTestId("map-and-label-map"); @@ -328,7 +341,7 @@ describe("copy feature select", () => { it.todo("is enabled once multiple features are present"); // copy select enabled once you add more features it.todo( - "lists all other features as options (the current feature is not listed)", + "lists all other features as options (the current feature is not listed)" ); // current tree is not an option in the copy select it.todo("copies all data from one feature to another"); @@ -350,11 +363,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 1a8586d85c..1873246808 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[] = []; @@ -32,19 +32,6 @@ export const addMultipleFeatures = ( }); }; -export const fillOutForm = async (user: UserEvent) => { - const speciesInput = screen.getByLabelText("Species"); - await user.type(speciesInput, mockTreeData.species); - const workInput = screen.getByLabelText("Proposed work"); - await user.type(workInput, mockTreeData.work); - const justificationInput = screen.getByLabelText("Justification"); - await user.type(justificationInput, mockTreeData.justification); - const urgencyDiv = screen.getByTitle("Urgency"); - const urgencySelect = within(urgencyDiv).getByRole("combobox"); - await user.click(urgencySelect); - await user.click(screen.getByRole("option", { name: /low/i })); -}; - export const fillOutFirstHalfOfForm = async (user: UserEvent) => { const speciesInput = screen.getByLabelText("Species"); await user.type(speciesInput, mockTreeData.species); @@ -61,6 +48,11 @@ export const fillOutSecondHalfOfForm = async (user: UserEvent) => { await user.click(screen.getByRole("option", { name: /low/i })); }; +export const fillOutForm = async (user: UserEvent) => { + await fillOutFirstHalfOfForm(user); + await fillOutSecondHalfOfForm(user); +}; + export const clickContinue = async (user: UserEvent) => { const continueButton = screen.getByRole("button", { name: /Continue/ }); await user.click(continueButton); From 222db29b476a862c097afea99c7aa0efa65e8531 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Sep 2024 14:29:30 +0100 Subject: [PATCH 9/9] remove redundant imports / variables --- .../src/@planx/components/MapAndLabel/Public/index.test.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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 39a9b7dd87..c79f02117e 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 @@ -121,7 +121,6 @@ describe("validation and error handling", () => { // it shows all fields are required in a tab it("should show all fields are required, for all feature tabs", async () => { const { getByTestId, getByRole, user } = setup(); - getByTestId("map-and-label-map"); addMultipleFeatures([point1, point2]); @@ -156,7 +155,6 @@ describe("validation and error handling", () => { // it shows all fields are required across different tabs it("should show an error if the minimum number of items is not met", async () => { const { getByTestId, user } = setup(); - getByTestId("map-and-label-map"); await clickContinue(user); @@ -235,8 +233,7 @@ describe("basic interactions - happy path", () => { }); it("adding multiple features to the map adds multiple feature tabs", async () => { - const { getByTestId, queryByRole } = setup(); - const map = getByTestId("map-and-label-map"); + const { queryByRole } = setup(); addMultipleFeatures([point1, point2, point3]); @@ -288,7 +285,6 @@ describe("basic interactions - happy path", () => { }); it("a user can input details on feature tabs in any order", async () => { const { getByTestId, getByRole, user } = setup(); - const map = getByTestId("map-and-label-map"); addMultipleFeatures([point1, point2]);