Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: E2E Testing for Planning Constraints #4063

Merged
merged 12 commits into from
Dec 20, 2024
56 changes: 51 additions & 5 deletions e2e/tests/ui-driven/src/create-flow-with-geospatial.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import {
} from "./helpers/context";
import { getTeamPage } from "./helpers/getPage";
import { createAuthenticatedSession } from "./helpers/globalHelpers";
import {
answerFindProperty,
answerQuestion,
clickContinue,
} from "./helpers/userActions";
import { answerQuestion, clickContinue } from "./helpers/userActions";
import { PlaywrightEditor } from "./pages/Editor";
import {
navigateToService,
Expand All @@ -37,6 +33,15 @@ import {
setupOSMapsStyles,
setupOSMapsVectorTiles,
} from "./mocks/osMapsResponse";
import {
planningConstraintHeadersMock,
setupGISMockResponse,
setupRoadsMockResponse,
} from "./mocks/gisResponse";
import {
answerFindProperty,
userChallengesPlanningConstraint,
} from "./helpers/geoSpatialUserActions";

test.describe("Flow creation, publish and preview", () => {
let context: TestContext = {
Expand Down Expand Up @@ -133,6 +138,9 @@ test.describe("Flow creation, publish and preview", () => {
setupOSMapsStyles(page);
setupOSMapsVectorTiles(page);

await setupGISMockResponse(page);
await setupRoadsMockResponse(page);

await expect(
page.locator("h1", { hasText: "Find the property" }),
).toBeVisible();
Expand Down Expand Up @@ -225,6 +233,44 @@ test.describe("Flow creation, publish and preview", () => {
"The correct value for area comes from the map properties ",
).toBeVisible();

await clickContinue({ page });

await expect(
page.locator("h1", { hasText: "Planning constraints" }),
).toBeVisible();

await expect(
page.getByText(
"These are the planning constraints we think apply to this property",
),
).toBeVisible();

const listedBuildingConstraintRowItem = page.getByRole("button", {
name: "Listed building outlines",
});

await expect(listedBuildingConstraintRowItem).toBeVisible();

await listedBuildingConstraintRowItem.click();

await userChallengesPlanningConstraint(page);

await expect(
listedBuildingConstraintRowItem.getByText("Marked as not applicable"),
).toBeVisible();

// click to hide constraint data
await listedBuildingConstraintRowItem.click();

// ensure constraints that don't apply show up
await page
.getByRole("button", { name: "Constraints that don't apply" })
.click();

const dontApplyHeadings = await page.getByRole("heading").allTextContents();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: should this rather sit in a unit test?


expect(dontApplyHeadings).toEqual(planningConstraintHeadersMock);

// TODO: answer uploadAndLabel
// TODO: answerPropertyInfo, answerPlanningConstraints
});
Expand Down
4 changes: 4 additions & 0 deletions e2e/tests/ui-driven/src/helpers/addComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ const createBaseComponent = async (
await page.getByLabel("Show users a 'change' link to").click();
break;
case ComponentType.PlanningConstraints:
await page
.getByRole("row", { name: "via Planning Data: conservation-area" })
.locator("span")
.click();
break;
case ComponentType.DrawBoundary:
break;
Expand Down
20 changes: 20 additions & 0 deletions e2e/tests/ui-driven/src/helpers/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ export async function setUpTestContext(
submissionEmail: context.team.settings?.submissionEmail,
},
});

// has_planning_data needs to be altered manually for geospatial tests
await $admin.client.request(
gql`
mutation TogglePlanningData($teamId: Int) {
update_team_integrations(
where: { team_id: { _eq: $teamId } }
_set: { has_planning_data: true }
) {
returning {
has_planning_data
team_id
}
}
}
`,
{
teamId: context.team.id,
},
);
}
if (
context.flow &&
Expand Down
40 changes: 40 additions & 0 deletions e2e/tests/ui-driven/src/helpers/geoSpatialUserActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect, Page } from "@playwright/test";
import { setupOSMockResponse } from "../mocks/osPlacesResponse";

export async function answerFindProperty(page: Page) {
await setupOSMockResponse(page);
await page.getByLabel("Postcode").fill("SW1 1AA");
await page.getByLabel("Select an address").click();
await page.getByRole("option").first().click();
}

export const userChallengesPlanningConstraint = async (page: Page) => {
const thisDoesNotApplyConstraintButton = page.getByRole("button", {
name: "I don't think this constraint applies to this property",
});

await thisDoesNotApplyConstraintButton.click();

const constraintDoesNotApplyDialog = page.getByRole("heading", {
name: "I don't think this constraint applies to this property",
});
await constraintDoesNotApplyDialog.isVisible();

const noAddressSuppliedButton = page.getByTestId("entity-checkbox-42103309");
await noAddressSuppliedButton.click();

const tellUsWhyText = page.getByRole("textbox");
await tellUsWhyText.fill("This is the reason why");

const submitConstraintChallenge = page.getByTestId(
"override-modal-submit-button",
);
await submitConstraintChallenge.click();

await expect(
page.getByTestId("error-message-checklist-error-inaccurate-entities"),
).toBeHidden();
await expect(
page.getByTestId("error-message-input-error-inaccurate-entities"),
).toBeHidden();
};
8 changes: 0 additions & 8 deletions e2e/tests/ui-driven/src/helpers/userActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Locator, Page } from "@playwright/test";
import { expect } from "@playwright/test";
import { setupOSMockResponse } from "../mocks/osPlacesResponse";
import { findSessionId, getGraphQLClient } from "./context";
import { TEST_EMAIL, log, waitForDebugLog } from "./globalHelpers";
import { TestContext } from "./types";
Expand Down Expand Up @@ -194,13 +193,6 @@ export async function submitCardDetails(page: Page) {
await page.locator("#confirm").click();
}

export async function answerFindProperty(page: Page) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this to a separate geoSpatialUserActions doc to fit it better with the other ones

await setupOSMockResponse(page);
await page.getByLabel("Postcode").fill("SW1 1AA");
await page.getByLabel("Select an address").click();
await page.getByRole("option").first().click();
}

export async function answerContactInput(
page: Page,
{
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/ui-driven/src/invite-to-pay/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { TEST_EMAIL, addSessionToContext, log } from "../helpers/globalHelpers";
import {
answerChecklist,
answerContactInput,
answerFindProperty,
fillInEmail,
} from "../helpers/userActions";
import { TestContext } from "../helpers/types";
import { answerFindProperty } from "../helpers/geoSpatialUserActions";

/**
* Navigates to pay component whilst completing the minimum requirements for an Invite to Pay flow
Expand Down
20 changes: 20 additions & 0 deletions e2e/tests/ui-driven/src/mocks/geospatialMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,23 @@ export const mockChangedMapGeoJson: GeoJsonChangeHandler = {
"area.hectares": 0.001072,
},
};

export const mockRoadData = {
sourceRequest:
"https://api.os.uk/features/v1/wfs?service=WFS&request=GetFeature&version=2.0.0&typeNames=Highways_RoadLink&outputFormat=GEOJSON&srsName=urn%3Aogc%3Adef%3Acrs%3AEPSG%3A%3A4326&count=1&filter=%0A++++%3Cogc%3AFilter%3E%0A++++++%3Cogc%3APropertyIsLike+wildCard%3D%22%25%22+singleChar%3D%22%23%22+escapeChar%3D%22%21%22%3E%0A++++++++%3Cogc%3APropertyName%3EFormsPartOf%3C%2Fogc%3APropertyName%3E%0A++++++++%3Cogc%3ALiteral%3E%25Street%23usrn21900651%25%3C%2Fogc%3ALiteral%3E%0A++++++%3C%2Fogc%3APropertyIsLike%3E%0A++++%3C%2Fogc%3AFilter%3E%0A++&",
metadata: {
"road.classified": {
name: "Classified road",
plural: "Classified roads",
text: "This will effect your project if you are looking to add a dropped kerb. It may also impact some agricultural or forestry projects within 25 metres of a classified road.",
},
},
constraints: {
"road.classified": {
fn: "road.classified",
value: false,
text: "is not on a Classified Road",
category: "General policy",
},
},
};
44 changes: 44 additions & 0 deletions e2e/tests/ui-driven/src/mocks/gisResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { expect, Page } from "@playwright/test";
import { mockRoadData } from "./geospatialMocks";
import propertyConstraintsResponse from "./propertyConstraintResponse.json";

export async function setupGISMockResponse(page: Page) {
const gisDigitalLandEndpoint = "**/gis/E2E?geom*";
await page.route(gisDigitalLandEndpoint, async (route, request) => {
const urlContainsConstraints = checkGISMockRequestUrl(request.url());
expect(urlContainsConstraints).toEqual(true);
await route.fulfill({
status: 200,
body: JSON.stringify(propertyConstraintsResponse),
});
});
}

export function checkGISMockRequestUrl(url: string) {
const splitUrl = url.split("/").pop()?.split("%2C");
return (
!splitUrl?.includes("designated.conservationArea") &&
splitUrl?.includes("listed")
);
}

export async function setupRoadsMockResponse(page: Page) {
const gisRoadsEndpoint = new RegExp(/\/roads\?.*/);
await page.route(gisRoadsEndpoint, async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify(mockRoadData),
});
});
}

export const planningConstraintHeadersMock = [
"Planning constraints",
"These are the planning constraints we think apply to this property",
"Heritage and conservation",
"General policy",
"Heritage and conservation",
"Flooding",
"Ecology",
"Trees",
];
Loading
Loading