From 305af4e40f2d54af2baf66e88b27b6fc8872e8c3 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 3 Dec 2024 16:45:25 +0000 Subject: [PATCH 01/10] initial setup remove upload and label refs initial expects for area and uplaod file button --- .../ui-driven/src/create-flow-with-geospatial.spec.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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 8bc6fe181b..0eeaa75160 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 @@ -72,8 +72,7 @@ test.describe("Flow creation, publish and preview", () => { await editor.createInternalPortal(); await editor.populateInternalPortal(); await page.getByRole("link", { name: "start" }).click(); // return to main flow - await editor.createUploadAndLabel(); - // TODO: editor.createPropertyInfo() + // await editor.createUploadAndLabel(); await editor.createDrawBoundary(); await editor.createPlanningConstraints(); // await editor.createFileUpload(); @@ -81,7 +80,6 @@ test.describe("Flow creation, publish and preview", () => { await expect(editor.nodeList).toContainText([ "Find property", "an internal portalEdit Portal", - "Upload and label", "Confirm your location plan", "Planning constraints", // "File upload", @@ -169,7 +167,12 @@ test.describe("Flow creation, publish and preview", () => { ).toBeVisible(); await clickContinue({ page }); + await expect(page.getByRole('heading', { name: 'Confirm your location plan' })).toBeVisible() + + await expect(page.getByTestId('upload-file-button')).toBeVisible() + await expect(page.getByText("490.37")).toBeVisible() + // TODO: answer uploadAndLabel - // TODO: answerPropertyInfo, answerDrawBoundary, answerPlanningConstraints + // TODO: answerPropertyInfo, answerPlanningConstraints }); }); From 3bf71620023885c8cca97dc43e44785ca1e0fbcf Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 3 Dec 2024 18:43:53 +0000 Subject: [PATCH 02/10] check upload doc navigation and drawgeojson --- .../src/create-flow-with-geospatial.spec.ts | 23 +++++++++++++++---- .../ui-driven/src/helpers/geospatialChecks.ts | 5 ++-- 2 files changed, 22 insertions(+), 6 deletions(-) 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 0eeaa75160..1381cd2e5e 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 @@ -128,7 +128,7 @@ test.describe("Flow creation, publish and preview", () => { ).toBeVisible(); // Check map component has geoJson content - await checkGeoJsonContent(page, mockMapGeoJson); + await checkGeoJsonContent(page, "geojsondata" ,mockMapGeoJson); // Check property info is being shown await expect(page.getByText("Test Street, Testville")).toBeVisible(); @@ -167,11 +167,26 @@ test.describe("Flow creation, publish and preview", () => { ).toBeVisible(); await clickContinue({ page }); - await expect(page.getByRole('heading', { name: 'Confirm your location plan' })).toBeVisible() + const drawBoundaryTitle = page.getByRole('heading', { name: 'Confirm your location plan' }) + await expect(drawBoundaryTitle).toBeVisible() - await expect(page.getByTestId('upload-file-button')).toBeVisible() - await expect(page.getByText("490.37")).toBeVisible() + const uploadButton = page.getByTestId('upload-file-button') + + await expect(uploadButton).toBeVisible() + await expect(page.getByText("490.37"),"Checking for area text").toBeVisible() + await checkGeoJsonContent(page, "drawgeojsondata" ,mockMapGeoJson); + + await uploadButton.click() + await expect(page.getByRole('heading', { name: 'Upload a location plan' }), "Ensure we can navigate to upload location plan").toBeVisible() + + // const uploadFileButton = page.getByRole('button', { name: 'Drop file here or choose' }) + const useMapButton = page.getByTestId('use-map-button') + + await useMapButton.click() + + await expect(drawBoundaryTitle, "Ensure we've navigated back to the map component").toBeVisible() + // TODO: answer uploadAndLabel // TODO: answerPropertyInfo, answerPlanningConstraints }); diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index 7b55e01997..e242e2007a 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -1,12 +1,13 @@ import { expect, Page } from "@playwright/test"; import { Feature } from "geojson"; -export const checkGeoJsonContent = async (page: Page, geoJson: Feature) => { +export const checkGeoJsonContent = async (page: Page, attribute:"geojsondata" | "drawgeojsondata", geoJson: Feature) => { // Wait for the map component to be present const mapComponent = await page.waitForSelector("my-map"); // Get the geojsonData attribute - const geojsonData = await mapComponent.getAttribute("geojsondata"); + const geojsonData = await mapComponent.getAttribute(attribute); expect(JSON.parse(geojsonData!)).toEqual(geoJson); }; + From 576ca54c60f37fad8795e7586e2970b1c2649540 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 3 Dec 2024 18:44:31 +0000 Subject: [PATCH 03/10] lint:fix --- .../src/create-flow-with-geospatial.spec.ts | 39 ++++++++++++------- .../ui-driven/src/helpers/geospatialChecks.ts | 7 +++- 2 files changed, 30 insertions(+), 16 deletions(-) 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 1381cd2e5e..68974ad144 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 @@ -128,7 +128,7 @@ test.describe("Flow creation, publish and preview", () => { ).toBeVisible(); // Check map component has geoJson content - await checkGeoJsonContent(page, "geojsondata" ,mockMapGeoJson); + await checkGeoJsonContent(page, "geojsondata", mockMapGeoJson); // Check property info is being shown await expect(page.getByText("Test Street, Testville")).toBeVisible(); @@ -167,26 +167,37 @@ test.describe("Flow creation, publish and preview", () => { ).toBeVisible(); await clickContinue({ page }); - const drawBoundaryTitle = page.getByRole('heading', { name: 'Confirm your location plan' }) - await expect(drawBoundaryTitle).toBeVisible() + const drawBoundaryTitle = page.getByRole("heading", { + name: "Confirm your location plan", + }); + await expect(drawBoundaryTitle).toBeVisible(); - const uploadButton = page.getByTestId('upload-file-button') - - await expect(uploadButton).toBeVisible() - await expect(page.getByText("490.37"),"Checking for area text").toBeVisible() + const uploadButton = page.getByTestId("upload-file-button"); - await checkGeoJsonContent(page, "drawgeojsondata" ,mockMapGeoJson); + await expect(uploadButton).toBeVisible(); + await expect( + page.getByText("490.37"), + "Checking for area text", + ).toBeVisible(); - await uploadButton.click() - await expect(page.getByRole('heading', { name: 'Upload a location plan' }), "Ensure we can navigate to upload location plan").toBeVisible() + await checkGeoJsonContent(page, "drawgeojsondata", mockMapGeoJson); + + await uploadButton.click(); + await expect( + page.getByRole("heading", { name: "Upload a location plan" }), + "Ensure we can navigate to upload location plan", + ).toBeVisible(); // const uploadFileButton = page.getByRole('button', { name: 'Drop file here or choose' }) - const useMapButton = page.getByTestId('use-map-button') + const useMapButton = page.getByTestId("use-map-button"); + + await useMapButton.click(); - await useMapButton.click() + await expect( + drawBoundaryTitle, + "Ensure we've navigated back to the map component", + ).toBeVisible(); - await expect(drawBoundaryTitle, "Ensure we've navigated back to the map component").toBeVisible() - // TODO: answer uploadAndLabel // TODO: answerPropertyInfo, answerPlanningConstraints }); diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index e242e2007a..ed5f5b3f0a 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -1,7 +1,11 @@ import { expect, Page } from "@playwright/test"; import { Feature } from "geojson"; -export const checkGeoJsonContent = async (page: Page, attribute:"geojsondata" | "drawgeojsondata", geoJson: Feature) => { +export const checkGeoJsonContent = async ( + page: Page, + attribute: "geojsondata" | "drawgeojsondata", + geoJson: Feature, +) => { // Wait for the map component to be present const mapComponent = await page.waitForSelector("my-map"); @@ -10,4 +14,3 @@ export const checkGeoJsonContent = async (page: Page, attribute:"geojsondata" | expect(JSON.parse(geojsonData!)).toEqual(geoJson); }; - From ea3e0c44914d2b544c2a4492c7ba4ff4720e1cdf Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Mon, 9 Dec 2024 15:10:15 +0000 Subject: [PATCH 04/10] refine draw boundary checks --- .../src/create-flow-with-geospatial.spec.ts | 30 +++++++---------- .../ui-driven/src/helpers/geospatialChecks.ts | 33 +++++++++++++++++++ 2 files changed, 44 insertions(+), 19 deletions(-) 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 68974ad144..c6b20ff752 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 @@ -19,11 +19,15 @@ import { } from "./helpers/navigateAndPublish"; import { TestContext } from "./helpers/types"; import { serviceProps } from "./helpers/serviceData"; -import { checkGeoJsonContent } from "./helpers/geospatialChecks"; +import { + checkGeoJsonContent, + checkUploadFileAltRoute, +} from "./helpers/geospatialChecks"; import { mockMapGeoJson, mockPropertyTypeOptions, } from "./mocks/geospatialMocks"; +import exp from "node:constants"; test.describe("Flow creation, publish and preview", () => { let context: TestContext = { @@ -170,32 +174,20 @@ test.describe("Flow creation, publish and preview", () => { const drawBoundaryTitle = page.getByRole("heading", { name: "Confirm your location plan", }); - await expect(drawBoundaryTitle).toBeVisible(); - - const uploadButton = page.getByTestId("upload-file-button"); - - await expect(uploadButton).toBeVisible(); await expect( - page.getByText("490.37"), - "Checking for area text", + drawBoundaryTitle, + "We are in the Draw Boundary component", ).toBeVisible(); await checkGeoJsonContent(page, "drawgeojsondata", mockMapGeoJson); - await uploadButton.click(); - await expect( - page.getByRole("heading", { name: "Upload a location plan" }), - "Ensure we can navigate to upload location plan", - ).toBeVisible(); - - // const uploadFileButton = page.getByRole('button', { name: 'Drop file here or choose' }) - const useMapButton = page.getByTestId("use-map-button"); - - await useMapButton.click(); + // navigate to upload file page + await checkUploadFileAltRoute(page); + // ensure we are back on the Draw Boundary component await expect( drawBoundaryTitle, - "Ensure we've navigated back to the map component", + "We have navigated back to the map component", ).toBeVisible(); // TODO: answer uploadAndLabel diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index ed5f5b3f0a..c0b2a43a21 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -8,9 +8,42 @@ export const checkGeoJsonContent = async ( ) => { // Wait for the map component to be present const mapComponent = await page.waitForSelector("my-map"); + await expect( + page.getByTestId("map-test-id"), + "Check we can see the map", + ).toBeVisible(); // Get the geojsonData attribute const geojsonData = await mapComponent.getAttribute(attribute); expect(JSON.parse(geojsonData!)).toEqual(geoJson); }; + +export const checkUploadFileAltRoute = async (page: Page) => { + const uploadButton = page.getByTestId("upload-file-button"); + + await expect( + uploadButton, + "We can see a button to upload a file instead", + ).toBeVisible(); + await expect( + page.getByText("490.37"), + "We can see a value for area", + ).toBeVisible(); + + await uploadButton.click(); + + await expect( + page.getByRole("heading", { name: "Upload a location plan" }), + "Should be in a page for uploading a file", + ).toBeVisible(); + + await expect( + page.getByRole("button", { name: "Drop file here or choose" }), + "A button for uploading files is visible", + ).toBeVisible(); + + const useMapButton = page.getByTestId("use-map-button"); + + await useMapButton.click(); +}; From 75611d4a2cc550c18e4640c0a74593a8996642b8 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 10 Dec 2024 16:17:47 +0000 Subject: [PATCH 05/10] refine geospatial mocks and add map interaction --- .../src/create-flow-with-geospatial.spec.ts | 31 +++++++++- .../ui-driven/src/helpers/geospatialChecks.ts | 42 ++++++++++++-- .../ui-driven/src/mocks/geospatialMocks.ts | 58 ++++++++++++++----- .../components/DrawBoundary/Public/index.tsx | 2 +- 4 files changed, 108 insertions(+), 25 deletions(-) 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 c6b20ff752..c535231a5e 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 @@ -20,14 +20,19 @@ import { import { TestContext } from "./helpers/types"; import { serviceProps } from "./helpers/serviceData"; import { + alterDrawGeoJson, checkGeoJsonContent, checkUploadFileAltRoute, + getMapProperties, + resetMapBoundary, + waitForMapComponent, } from "./helpers/geospatialChecks"; import { + GeoJsonChangeHandler, + mockChangedMapGeoJson, mockMapGeoJson, mockPropertyTypeOptions, } from "./mocks/geospatialMocks"; -import exp from "node:constants"; test.describe("Flow creation, publish and preview", () => { let context: TestContext = { @@ -181,15 +186,37 @@ test.describe("Flow creation, publish and preview", () => { await checkGeoJsonContent(page, "drawgeojsondata", mockMapGeoJson); + const area = "490.37"; + + await expect( + page.getByText(area), + "We can see a value for area", + ).toBeVisible(); + // navigate to upload file page await checkUploadFileAltRoute(page); - // ensure we are back on the Draw Boundary component await expect( drawBoundaryTitle, "We have navigated back to the map component", ).toBeVisible(); + await waitForMapComponent(page); + + await resetMapBoundary(page); + await alterDrawGeoJson(page); + + // extra new GeoJSON data + const newGeoJSON = await getMapProperties(page, "drawgeojsondata"); + const parsedJson: GeoJsonChangeHandler = JSON.parse(newGeoJSON!); + + await checkGeoJsonContent(page, "drawgeojsondata", mockChangedMapGeoJson); + + await expect( + page.getByText(`${parsedJson.properties!["area.squareMetres"]}`), + "We can see a new value for area", + ).toBeVisible(); + // TODO: answer uploadAndLabel // TODO: answerPropertyInfo, answerPlanningConstraints }); diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index c0b2a43a21..26c4408ef8 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -1,6 +1,38 @@ -import { expect, Page } from "@playwright/test"; +import { expect, Page } from "@playwright/test"; import { Feature } from "geojson"; +export const waitForMapComponent = async (page: Page) => { + await page.waitForFunction(() => { + const map = document.getElementById('draw-boundary-map') + return map + }); + +} + +export const getMapProperties = async (page: Page, attribute:"geojsondata" | "drawgeojsondata") => { + const mapComponent = await page.waitForSelector("my-map"); + return await mapComponent.getAttribute(attribute); +} + +export const alterDrawGeoJson = async (page: Page) => { +const map = page.getByTestId('map-test-id') + +await map.click({button:"left", position:{x:100, y:200}}) +await map.click({button:"left", position:{x:150, y:250}}) +await map.click({button:"left", position:{x:200, y:250}}) +await map.click({button:"left", position:{x:100, y:200}}) + + } + + export const resetMapBoundary = async (page: Page)=>{ + const resetButton = page.getByLabel('Reset map view') + await resetButton.click() + + const resetGeoJson = await getMapProperties(page, "drawgeojsondata") + + expect(resetGeoJson, "drawGeoJsonData should be reset").toEqual(null) + } + export const checkGeoJsonContent = async ( page: Page, attribute: "geojsondata" | "drawgeojsondata", @@ -8,6 +40,8 @@ export const checkGeoJsonContent = async ( ) => { // Wait for the map component to be present const mapComponent = await page.waitForSelector("my-map"); + + await page.waitForFunction(() => customElements.get('my-map')); await expect( page.getByTestId("map-test-id"), "Check we can see the map", @@ -16,7 +50,7 @@ export const checkGeoJsonContent = async ( // Get the geojsonData attribute const geojsonData = await mapComponent.getAttribute(attribute); - expect(JSON.parse(geojsonData!)).toEqual(geoJson); + expect(JSON.parse(geojsonData!), "map attribute matches expected mock attribute").toEqual(geoJson); }; export const checkUploadFileAltRoute = async (page: Page) => { @@ -26,10 +60,6 @@ export const checkUploadFileAltRoute = async (page: Page) => { uploadButton, "We can see a button to upload a file instead", ).toBeVisible(); - await expect( - page.getByText("490.37"), - "We can see a value for area", - ).toBeVisible(); await uploadButton.click(); diff --git a/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts b/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts index fb26308b1d..e56646bf73 100644 --- a/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts +++ b/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts @@ -1,29 +1,35 @@ import { OptionWithDataValues } from "../helpers/types"; +import { Feature, Polygon, Position } from "geojson"; + +type ChangeHandlerProperties = { + label: string; + "area.squareMetres": number; + "area.hectares": number; +}; + +export type GeoJsonChangeHandler = Feature; export const mockPropertyTypeOptions: OptionWithDataValues[] = [ { optionText: "Residential", dataValue: "residential" }, { optionText: "Commercial", dataValue: "commercial" }, ]; -import { Feature } from "geojson"; +const mockCoordinates: Position[][][] = [ + [ + [ + [-0.633498, 51.605485], + [-0.633455, 51.605606], + [-0.633788, 51.605643], + [-0.634429, 51.605799], + [-0.634429, 51.605767], + [-0.633498, 51.605485], + ], + ], +]; export const mockMapGeoJson: Feature = { - geometry: { - type: "MultiPolygon", - coordinates: [ - [ - [ - [-0.633498, 51.605485], - [-0.633455, 51.605606], - [-0.633788, 51.605643], - [-0.634429, 51.605799], - [-0.634429, 51.605767], - [-0.633498, 51.605485], - ], - ], - ], - }, type: "Feature", + geometry: { type: "MultiPolygon", coordinates: mockCoordinates }, properties: { "entry-date": "2024-05-06", "start-date": "2010-05-12", @@ -37,3 +43,23 @@ export const mockMapGeoJson: Feature = { "organisation-entity": "13", }, }; + +export const mockChangedMapGeoJson: GeoJsonChangeHandler = { + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [ + [ + [-0.6341888375038146, 51.60562241658701], + [-0.6341217822784424, 51.605580770520504], + [-0.63405472705307, 51.605580770520504], + [-0.6341888375038146, 51.60562241658701], + ], + ], + }, + properties: { + label: "1", + "area.squareMetres": 10.72, + "area.hectares": 0.001072, + }, +}; diff --git a/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx b/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx index 8c533ae74b..943a7532cb 100644 --- a/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx +++ b/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx @@ -89,7 +89,7 @@ export default function Component(props: Props) { isMounted.current = true; const geojsonChangeHandler = ({ detail: geojson }: any) => { - if (geojson["EPSG:3857"]?.features) { + if (geojson["EPSG:3857"]?.features) { // only a single polygon can be drawn, so get first feature in geojson "FeatureCollection" setBoundary(geojson["EPSG:3857"].features[0]); setArea( From b4d18258b7b4dda812743650998241b542cbdfb7 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 10 Dec 2024 16:20:56 +0000 Subject: [PATCH 06/10] refine comments --- .../src/create-flow-with-geospatial.spec.ts | 11 ++-- .../ui-driven/src/helpers/geospatialChecks.ts | 50 ++++++++++--------- 2 files changed, 34 insertions(+), 27 deletions(-) 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 c535231a5e..90dda4f6d0 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 @@ -193,7 +193,7 @@ test.describe("Flow creation, publish and preview", () => { "We can see a value for area", ).toBeVisible(); - // navigate to upload file page + // navigate to upload file page and back await checkUploadFileAltRoute(page); await expect( @@ -201,15 +201,18 @@ test.describe("Flow creation, publish and preview", () => { "We have navigated back to the map component", ).toBeVisible(); + // ensure map has loaded correctly await waitForMapComponent(page); await resetMapBoundary(page); + await alterDrawGeoJson(page); - // extra new GeoJSON data - const newGeoJSON = await getMapProperties(page, "drawgeojsondata"); - const parsedJson: GeoJsonChangeHandler = JSON.parse(newGeoJSON!); + // extract new GeoJSON data + const newGeoJson = await getMapProperties(page, "drawgeojsondata"); + const parsedJson: GeoJsonChangeHandler = JSON.parse(newGeoJson!); + // check it matches our static mock await checkGeoJsonContent(page, "drawgeojsondata", mockChangedMapGeoJson); await expect( diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index 26c4408ef8..12a48f400e 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -1,37 +1,38 @@ -import { expect, Page } from "@playwright/test"; +import { expect, Page } from "@playwright/test"; import { Feature } from "geojson"; export const waitForMapComponent = async (page: Page) => { await page.waitForFunction(() => { - const map = document.getElementById('draw-boundary-map') - return map + const map = document.getElementById("draw-boundary-map"); + return map; }); +}; -} - -export const getMapProperties = async (page: Page, attribute:"geojsondata" | "drawgeojsondata") => { +export const getMapProperties = async ( + page: Page, + attribute: "geojsondata" | "drawgeojsondata", +) => { const mapComponent = await page.waitForSelector("my-map"); - return await mapComponent.getAttribute(attribute); -} + return await mapComponent.getAttribute(attribute); +}; export const alterDrawGeoJson = async (page: Page) => { -const map = page.getByTestId('map-test-id') - -await map.click({button:"left", position:{x:100, y:200}}) -await map.click({button:"left", position:{x:150, y:250}}) -await map.click({button:"left", position:{x:200, y:250}}) -await map.click({button:"left", position:{x:100, y:200}}) + const map = page.getByTestId("map-test-id"); - } + await map.click({ button: "left", position: { x: 100, y: 200 } }); + await map.click({ button: "left", position: { x: 150, y: 250 } }); + await map.click({ button: "left", position: { x: 200, y: 250 } }); + await map.click({ button: "left", position: { x: 100, y: 200 } }); +}; - export const resetMapBoundary = async (page: Page)=>{ - const resetButton = page.getByLabel('Reset map view') - await resetButton.click() +export const resetMapBoundary = async (page: Page) => { + const resetButton = page.getByLabel("Reset map view"); + await resetButton.click(); - const resetGeoJson = await getMapProperties(page, "drawgeojsondata") + const resetGeoJson = await getMapProperties(page, "drawgeojsondata"); - expect(resetGeoJson, "drawGeoJsonData should be reset").toEqual(null) - } + expect(resetGeoJson, "drawGeoJsonData should be reset").toEqual(null); +}; export const checkGeoJsonContent = async ( page: Page, @@ -41,7 +42,7 @@ export const checkGeoJsonContent = async ( // Wait for the map component to be present const mapComponent = await page.waitForSelector("my-map"); - await page.waitForFunction(() => customElements.get('my-map')); + await page.waitForFunction(() => customElements.get("my-map")); await expect( page.getByTestId("map-test-id"), "Check we can see the map", @@ -50,7 +51,10 @@ export const checkGeoJsonContent = async ( // Get the geojsonData attribute const geojsonData = await mapComponent.getAttribute(attribute); - expect(JSON.parse(geojsonData!), "map attribute matches expected mock attribute").toEqual(geoJson); + expect( + JSON.parse(geojsonData!), + "map attribute matches expected mock attribute", + ).toEqual(geoJson); }; export const checkUploadFileAltRoute = async (page: Page) => { From cd70fe50ef17e10252ac798a4717870ba4326663 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 10 Dec 2024 16:25:57 +0000 Subject: [PATCH 07/10] revert index file change in draw boundary --- .../src/@planx/components/DrawBoundary/Public/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx b/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx index 943a7532cb..8c533ae74b 100644 --- a/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx +++ b/editor.planx.uk/src/@planx/components/DrawBoundary/Public/index.tsx @@ -89,7 +89,7 @@ export default function Component(props: Props) { isMounted.current = true; const geojsonChangeHandler = ({ detail: geojson }: any) => { - if (geojson["EPSG:3857"]?.features) { + if (geojson["EPSG:3857"]?.features) { // only a single polygon can be drawn, so get first feature in geojson "FeatureCollection" setBoundary(geojson["EPSG:3857"].features[0]); setArea( From e2d253402911c1178a8dfad2681135b874a4a992 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Dec 2024 14:17:19 +0000 Subject: [PATCH 08/10] address comments on review address comments from review refine osMapsMocks rename OSMapMocks --- .../src/create-flow-with-geospatial.spec.ts | 16 ++++++----- .../ui-driven/src/mocks/geospatialMocks.ts | 28 +++++++++---------- .../ui-driven/src/mocks/osMapsMockData.ts | 20 +++++++++++++ .../ui-driven/src/mocks/osMapsResponse.ts | 27 ++++++++++++++++++ 4 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 e2e/tests/ui-driven/src/mocks/osMapsMockData.ts create mode 100644 e2e/tests/ui-driven/src/mocks/osMapsResponse.ts diff --git a/e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts b/e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts index 90dda4f6d0..88e34dc189 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 @@ -30,9 +30,10 @@ import { import { GeoJsonChangeHandler, mockChangedMapGeoJson, - mockMapGeoJson, mockPropertyTypeOptions, + mockTitleBoundaryGeoJson, } from "./mocks/geospatialMocks"; +import { setupOSMapsStyles, setupOSMapsVectorTiles } from "./mocks/osMapsResponse"; test.describe("Flow creation, publish and preview", () => { let context: TestContext = { @@ -126,6 +127,9 @@ test.describe("Flow creation, publish and preview", () => { `/${context.team.slug}/${serviceProps.slug}/published?analytics=false`, ); + setupOSMapsStyles(page) + setupOSMapsVectorTiles(page) + await expect( page.locator("h1", { hasText: "Find the property" }), ).toBeVisible(); @@ -137,7 +141,7 @@ test.describe("Flow creation, publish and preview", () => { ).toBeVisible(); // Check map component has geoJson content - await checkGeoJsonContent(page, "geojsondata", mockMapGeoJson); + await checkGeoJsonContent(page, "geojsondata", mockTitleBoundaryGeoJson); // Check property info is being shown await expect(page.getByText("Test Street, Testville")).toBeVisible(); @@ -181,16 +185,14 @@ test.describe("Flow creation, publish and preview", () => { }); await expect( drawBoundaryTitle, - "We are in the Draw Boundary component", ).toBeVisible(); - await checkGeoJsonContent(page, "drawgeojsondata", mockMapGeoJson); + await checkGeoJsonContent(page, "drawgeojsondata", mockTitleBoundaryGeoJson); - const area = "490.37"; + const area = "The property boundary you have drawn is 490.37"; await expect( page.getByText(area), - "We can see a value for area", ).toBeVisible(); // navigate to upload file page and back @@ -217,7 +219,7 @@ test.describe("Flow creation, publish and preview", () => { await expect( page.getByText(`${parsedJson.properties!["area.squareMetres"]}`), - "We can see a new value for area", + "The correct value for area comes from the map properties ", ).toBeVisible(); // TODO: answer uploadAndLabel diff --git a/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts b/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts index e56646bf73..bca773dca2 100644 --- a/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts +++ b/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts @@ -1,5 +1,5 @@ import { OptionWithDataValues } from "../helpers/types"; -import { Feature, Polygon, Position } from "geojson"; +import { Feature, Polygon } from "geojson"; type ChangeHandlerProperties = { label: string; @@ -14,22 +14,20 @@ export const mockPropertyTypeOptions: OptionWithDataValues[] = [ { optionText: "Commercial", dataValue: "commercial" }, ]; -const mockCoordinates: Position[][][] = [ - [ +export const mockTitleBoundaryGeoJson: Feature = { + type: "Feature", + geometry: { type: "MultiPolygon", coordinates: [ [ - [-0.633498, 51.605485], - [-0.633455, 51.605606], - [-0.633788, 51.605643], - [-0.634429, 51.605799], - [-0.634429, 51.605767], - [-0.633498, 51.605485], + [ + [-0.633498, 51.605485], + [-0.633455, 51.605606], + [-0.633788, 51.605643], + [-0.634429, 51.605799], + [-0.634429, 51.605767], + [-0.633498, 51.605485], + ], ], - ], -]; - -export const mockMapGeoJson: Feature = { - type: "Feature", - geometry: { type: "MultiPolygon", coordinates: mockCoordinates }, + ]}, properties: { "entry-date": "2024-05-06", "start-date": "2010-05-12", diff --git a/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts b/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts new file mode 100644 index 0000000000..3df672f0ef --- /dev/null +++ b/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts @@ -0,0 +1,20 @@ +export const osMapsStylesResponse = { + version: 8, + sprite: "https://api.os.uk/maps/vector/v1/vts/resources/sprites/sprite?key=YOUR_KEY&srs=3857", + glyphs: "https://api.os.uk/maps/vector/v1/vts/resources/fonts/{fontstack}/{range}.pbf?key=YOUR_KEY&srs=3857", + sources: { + esri: { + type: "vector", + url: "https://api.os.uk/maps/vector/v1/vts?key=YOUR_KEY&srs=3857" + } + }, + layers: [ + { + id: "background", + type: "background", + paint: { + "background-color": "#0437F2" + } + }, + ] + }; \ No newline at end of file diff --git a/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts b/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts new file mode 100644 index 0000000000..ae48bd1d96 --- /dev/null +++ b/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts @@ -0,0 +1,27 @@ +import { Page } from "@playwright/test"; +import { osMapsStylesResponse } from "./osMapsMockData"; + +export async function setupOSMapsStyles(page: Page) { + const ordnanceSurveyMapsStyles = new RegExp( + /\/proxy\/ordnance-survey\/maps\/vector\/v1\/vts\/resources\/styles.*/, + ); + await page.route(ordnanceSurveyMapsStyles, async (route) => { + await route.fulfill({ + status: 200, + body: JSON.stringify(osMapsStylesResponse), + }); + }); +} + +export async function setupOSMapsVectorTiles(page: Page){ + const ordnanceSurveyVectorTiles = new RegExp( + /\/proxy\/ordnance-survey\/maps\/vector\/v1\/vts\/tile/, + ) + + await page.route(ordnanceSurveyVectorTiles, async (route) => { + await route.fulfill({ + status: 200, + body: Buffer.from([]), + }); + }); +} \ No newline at end of file From 14a07bd21ee459b7390695621d8c269fef3b46a2 Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Dec 2024 14:27:27 +0000 Subject: [PATCH 09/10] Add error message check on file upload --- e2e/tests/ui-driven/src/helpers/geospatialChecks.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index 12a48f400e..6bde8ef3fb 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -77,6 +77,10 @@ export const checkUploadFileAltRoute = async (page: Page) => { "A button for uploading files is visible", ).toBeVisible(); + await page.getByTestId('continue-button').click() + + await page.getByTestId('error-message-upload-location-plan').isVisible() + const useMapButton = page.getByTestId("use-map-button"); await useMapButton.click(); From ab3401832140744324a79cdfbe97d90665438cda Mon Sep 17 00:00:00 2001 From: Rory Doak Date: Tue, 17 Dec 2024 14:42:24 +0000 Subject: [PATCH 10/10] lint:fix --- .../src/create-flow-with-geospatial.spec.ts | 23 ++++++------ .../ui-driven/src/helpers/geospatialChecks.ts | 4 +-- .../ui-driven/src/mocks/geospatialMocks.ts | 21 ++++++----- .../ui-driven/src/mocks/osMapsMockData.ts | 36 ++++++++++--------- .../ui-driven/src/mocks/osMapsResponse.ts | 22 ++++++------ 5 files changed, 57 insertions(+), 49 deletions(-) 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 88e34dc189..02ecfbc29e 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 @@ -33,7 +33,10 @@ import { mockPropertyTypeOptions, mockTitleBoundaryGeoJson, } from "./mocks/geospatialMocks"; -import { setupOSMapsStyles, setupOSMapsVectorTiles } from "./mocks/osMapsResponse"; +import { + setupOSMapsStyles, + setupOSMapsVectorTiles, +} from "./mocks/osMapsResponse"; test.describe("Flow creation, publish and preview", () => { let context: TestContext = { @@ -127,8 +130,8 @@ test.describe("Flow creation, publish and preview", () => { `/${context.team.slug}/${serviceProps.slug}/published?analytics=false`, ); - setupOSMapsStyles(page) - setupOSMapsVectorTiles(page) + setupOSMapsStyles(page); + setupOSMapsVectorTiles(page); await expect( page.locator("h1", { hasText: "Find the property" }), @@ -183,17 +186,17 @@ test.describe("Flow creation, publish and preview", () => { const drawBoundaryTitle = page.getByRole("heading", { name: "Confirm your location plan", }); - await expect( - drawBoundaryTitle, - ).toBeVisible(); + await expect(drawBoundaryTitle).toBeVisible(); - await checkGeoJsonContent(page, "drawgeojsondata", mockTitleBoundaryGeoJson); + await checkGeoJsonContent( + page, + "drawgeojsondata", + mockTitleBoundaryGeoJson, + ); const area = "The property boundary you have drawn is 490.37"; - await expect( - page.getByText(area), - ).toBeVisible(); + await expect(page.getByText(area)).toBeVisible(); // navigate to upload file page and back await checkUploadFileAltRoute(page); diff --git a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts index 6bde8ef3fb..ea13894975 100644 --- a/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts +++ b/e2e/tests/ui-driven/src/helpers/geospatialChecks.ts @@ -77,9 +77,9 @@ export const checkUploadFileAltRoute = async (page: Page) => { "A button for uploading files is visible", ).toBeVisible(); - await page.getByTestId('continue-button').click() + await page.getByTestId("continue-button").click(); - await page.getByTestId('error-message-upload-location-plan').isVisible() + await page.getByTestId("error-message-upload-location-plan").isVisible(); const useMapButton = page.getByTestId("use-map-button"); diff --git a/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts b/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts index bca773dca2..e923545f46 100644 --- a/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts +++ b/e2e/tests/ui-driven/src/mocks/geospatialMocks.ts @@ -16,18 +16,21 @@ export const mockPropertyTypeOptions: OptionWithDataValues[] = [ export const mockTitleBoundaryGeoJson: Feature = { type: "Feature", - geometry: { type: "MultiPolygon", coordinates: [ - [ + geometry: { + type: "MultiPolygon", + coordinates: [ [ - [-0.633498, 51.605485], - [-0.633455, 51.605606], - [-0.633788, 51.605643], - [-0.634429, 51.605799], - [-0.634429, 51.605767], - [-0.633498, 51.605485], + [ + [-0.633498, 51.605485], + [-0.633455, 51.605606], + [-0.633788, 51.605643], + [-0.634429, 51.605799], + [-0.634429, 51.605767], + [-0.633498, 51.605485], + ], ], ], - ]}, + }, properties: { "entry-date": "2024-05-06", "start-date": "2010-05-12", diff --git a/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts b/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts index 3df672f0ef..b99f14f4d3 100644 --- a/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts +++ b/e2e/tests/ui-driven/src/mocks/osMapsMockData.ts @@ -1,20 +1,22 @@ export const osMapsStylesResponse = { - version: 8, - sprite: "https://api.os.uk/maps/vector/v1/vts/resources/sprites/sprite?key=YOUR_KEY&srs=3857", - glyphs: "https://api.os.uk/maps/vector/v1/vts/resources/fonts/{fontstack}/{range}.pbf?key=YOUR_KEY&srs=3857", - sources: { - esri: { - type: "vector", - url: "https://api.os.uk/maps/vector/v1/vts?key=YOUR_KEY&srs=3857" - } + version: 8, + sprite: + "https://api.os.uk/maps/vector/v1/vts/resources/sprites/sprite?key=YOUR_KEY&srs=3857", + glyphs: + "https://api.os.uk/maps/vector/v1/vts/resources/fonts/{fontstack}/{range}.pbf?key=YOUR_KEY&srs=3857", + sources: { + esri: { + type: "vector", + url: "https://api.os.uk/maps/vector/v1/vts?key=YOUR_KEY&srs=3857", }, - layers: [ - { - id: "background", - type: "background", - paint: { - "background-color": "#0437F2" - } + }, + layers: [ + { + id: "background", + type: "background", + paint: { + "background-color": "#0437F2", }, - ] - }; \ No newline at end of file + }, + ], +}; diff --git a/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts b/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts index ae48bd1d96..ccd6f6de6f 100644 --- a/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts +++ b/e2e/tests/ui-driven/src/mocks/osMapsResponse.ts @@ -13,15 +13,15 @@ export async function setupOSMapsStyles(page: Page) { }); } -export async function setupOSMapsVectorTiles(page: Page){ - const ordnanceSurveyVectorTiles = new RegExp( - /\/proxy\/ordnance-survey\/maps\/vector\/v1\/vts\/tile/, - ) +export async function setupOSMapsVectorTiles(page: Page) { + const ordnanceSurveyVectorTiles = new RegExp( + /\/proxy\/ordnance-survey\/maps\/vector\/v1\/vts\/tile/, + ); - await page.route(ordnanceSurveyVectorTiles, async (route) => { - await route.fulfill({ - status: 200, - body: Buffer.from([]), - }); - }); -} \ No newline at end of file + await page.route(ordnanceSurveyVectorTiles, async (route) => { + await route.fulfill({ + status: 200, + body: Buffer.from([]), + }); + }); +}