@ministryofjustice/hmpps-probation-integration-e2e-tests 1.119.0 → 1.121.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ministryofjustice/hmpps-probation-integration-e2e-tests",
3
3
  "description": "Playwright end to end tests for hmpps-probation-integration-services.",
4
- "version": "1.119.0",
4
+ "version": "1.121.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/ministryofjustice/hmpps-probation-integration-e2e-tests#readme",
7
7
  "bugs": {
@@ -71,6 +71,7 @@
71
71
  "./steps/cas1-approved-premises/applications/reallocate": "./steps/cas1-approved-premises/applications/reallocate.mjs",
72
72
  "./steps/cas1-approved-premises/applications/release-date-known-status": "./steps/cas1-approved-premises/applications/release-date-known-status.mjs",
73
73
  "./steps/cas1-approved-premises/applications/review-prison-information": "./steps/cas1-approved-premises/applications/review-prison-information.mjs",
74
+ "./steps/cas1-approved-premises/applications/select-ap-placing-reason": "./steps/cas1-approved-premises/applications/select-ap-placing-reason.mjs",
74
75
  "./steps/cas1-approved-premises/applications/select-offence": "./steps/cas1-approved-premises/applications/select-offence.mjs",
75
76
  "./steps/cas1-approved-premises/applications/select-sentence-type": "./steps/cas1-approved-premises/applications/select-sentence-type.mjs",
76
77
  "./steps/cas1-approved-premises/applications/select-situation-option": "./steps/cas1-approved-premises/applications/select-situation-option.mjs",
@@ -122,6 +123,7 @@
122
123
  "./steps/delius/logout": "./steps/delius/logout.mjs",
123
124
  "./steps/delius/oasys-rsr-score/verify-rsr-score": "./steps/delius/oasys-rsr-score/verify-rsr-score.mjs",
124
125
  "./steps/delius/offender/create-offender": "./steps/delius/offender/create-offender.mjs",
126
+ "./steps/delius/offender/delete-offender": "./steps/delius/offender/delete-offender.mjs",
125
127
  "./steps/delius/offender/find-offender": "./steps/delius/offender/find-offender.mjs",
126
128
  "./steps/delius/offender/update-offender": "./steps/delius/offender/update-offender.mjs",
127
129
  "./steps/delius/registration/create-registration": "./steps/delius/registration/create-registration.mjs",
@@ -140,6 +142,7 @@
140
142
  "./steps/delius/utils/refresh": "./steps/delius/utils/refresh.mjs",
141
143
  "./steps/dps/caseload": "./steps/dps/caseload.mjs",
142
144
  "./steps/dps/login": "./steps/dps/login.mjs",
145
+ "./steps/esupervision/check-in": "./steps/esupervision/check-in.mjs",
143
146
  "./steps/hdc-licences/login": "./steps/hdc-licences/login.mjs",
144
147
  "./steps/hmpps-auth/login": "./steps/hmpps-auth/login.mjs",
145
148
  "./steps/k8s/k8s-utils": "./steps/k8s/k8s-utils.mjs",
@@ -22,6 +22,7 @@ const assessApplication = async (page, personName) => {
22
22
  await page.getByRole("group", { name: "Does the application identify the risk factors that an Approved Premises (AP) placement can support?" }).getByLabel("Yes").check();
23
23
  await page.getByRole("group", { name: "Does the application explain how an AP placement would be beneficial for risk management?" }).getByLabel("Yes").check();
24
24
  await page.getByRole("group", { name: "Are there factors to consider regarding the location of placement?" }).getByLabel("No").check();
25
+ await page.locator("#locationOfPlacementComments").fill("Test risk factors regarding location");
25
26
  await page.getByRole("group", { name: "Is the move on plan sufficient?" }).getByLabel("Yes").check();
26
27
  await page.getByRole("button", { name: "Submit" }).click();
27
28
  await expect(page.locator(".govuk-heading-l")).toHaveText("Application timeliness");
@@ -44,18 +45,9 @@ const assessApplication = async (page, personName) => {
44
45
  await page.getByRole("button", { name: "Submit" }).click();
45
46
  await page.getByRole("link", { name: "Matching information" }).click();
46
47
  await page.getByLabel("Standard AP").check();
47
- await page.getByLabel("Is wheelchair designated notRelevant").check();
48
- await page.getByLabel("Is single notRelevant").check();
49
- await page.getByLabel("Is step free designated notRelevant").check();
50
- await page.getByLabel("Is catered notRelevant").check();
51
- await page.getByLabel("Has en suite notRelevant").check();
52
- await page.getByLabel("Is suited for sex offenders notRelevant").check();
53
- await page.getByLabel("Is suitable for vulnerable notRelevant").check();
54
- await page.getByLabel("Accepts sex offenders notRelevant").check();
55
- await page.getByLabel("Accepts child sex offenders notRelevant").check();
56
- await page.getByLabel("Accepts non sexual child offenders notRelevant").check();
57
- await page.getByLabel("Accepts hate crime offenders notRelevant").check();
58
- await page.getByLabel("Yes").check();
48
+ await page.getByRole("radio", { name: "Is step free designated required" }).check();
49
+ await page.getByRole("radio", { name: "Has en suite required" }).check();
50
+ await page.getByRole("radio", { name: "Yes" }).check();
59
51
  await page.getByRole("button", { name: "Submit" }).click();
60
52
  await page.getByRole("link", { name: "Check assessment answers" }).click();
61
53
  await page.getByRole("button", { name: "Continue" }).click();
@@ -0,0 +1,6 @@
1
+ import { Page } from "@playwright/test";
2
+
3
+ //#region steps/cas1-approved-premises/applications/select-ap-placing-reason.d.ts
4
+ declare const selectAPPlacingReason: (page: Page) => Promise<void>;
5
+ //#endregion
6
+ export { selectAPPlacingReason };
@@ -0,0 +1,11 @@
1
+ import { expect } from "@playwright/test";
2
+
3
+ //#region steps/cas1-approved-premises/applications/select-ap-placing-reason.ts
4
+ const selectAPPlacingReason = async (page) => {
5
+ await page.getByLabel("Application for risk management/public protection").check();
6
+ await page.locator(".govuk-button", { hasText: "Save and continue" }).click();
7
+ await expect(page.locator("#main-content h1")).toHaveText("Do you know the person's release date?");
8
+ };
9
+
10
+ //#endregion
11
+ export { selectAPPlacingReason };
@@ -2,6 +2,13 @@
2
2
  const selectOffence = async (page) => {
3
3
  await page.locator("[name=\"offenceId\"]").check();
4
4
  await page.locator(".govuk-button", { hasText: "Save and continue" }).click();
5
+ if (await page.locator(".govuk-heading-l", { hasText: "We cannot check this person's tier" }).isVisible()) {
6
+ await page.getByRole("radio", {
7
+ name: "High risk",
8
+ exact: true
9
+ }).check();
10
+ await page.locator(".govuk-button", { hasText: "Save and continue" }).click();
11
+ }
5
12
  };
6
13
 
7
14
  //#endregion
@@ -4,7 +4,7 @@ import { expect } from "@playwright/test";
4
4
  const selectSentenceType = async (page) => {
5
5
  await page.getByLabel("Community Order").check();
6
6
  await page.locator(".govuk-button", { hasText: "Save and continue" }).click();
7
- await expect(page.locator("#main-content h1")).toHaveText("Which of the following options best describes the situation?");
7
+ await expect(page.locator("#main-content h1")).toHaveText("What is the reason for placing this person in an AP?");
8
8
  };
9
9
 
10
10
  //#endregion
@@ -25,7 +25,7 @@ const enterSedLedPssDates = async (page) => {
25
25
  await page.locator("#pssEndDate-month").fill(month);
26
26
  await page.locator("#pssEndDate-year").fill(year);
27
27
  await page.locator(".govuk-button", { hasText: "Save and continue" }).click();
28
- await expect(page.locator(".govuk-fieldset__heading")).toHaveText("Which of the following best describes the sentence type the person is on?");
28
+ await expect(page.locator(".govuk-fieldset__heading")).toHaveText("Which sentence type does the person have?");
29
29
  };
30
30
 
31
31
  //#endregion
@@ -1,6 +1,5 @@
1
1
  import { enterCRN } from "./enter-crn.mjs";
2
2
  import { selectSentenceType } from "./select-sentence-type.mjs";
3
- import { selectSituationOption } from "./select-situation-option.mjs";
4
3
  import { selectReleaseDateKnownStatus } from "./release-date-known-status.mjs";
5
4
  import { confirmPlacementStartdate } from "./placement-start-date.mjs";
6
5
  import { selectAPPlacementPurpose } from "./ap-placement-purpose.mjs";
@@ -18,6 +17,7 @@ import { addFurtherPlacementConsiderations } from "./futher-placement-considerat
18
17
  import { addMoveOnInformation } from "./add-move-on-info.mjs";
19
18
  import { attachReqrdDocuments } from "./attach-required-documents.mjs";
20
19
  import { checkYourAnswers } from "./check-your-answers.mjs";
20
+ import { selectAPPlacingReason } from "./select-ap-placing-reason.mjs";
21
21
  import { expect } from "@playwright/test";
22
22
 
23
23
  //#region steps/cas1-approved-premises/applications/submit-application-full.ts
@@ -28,7 +28,7 @@ const submitAPApplication = async (page, crn) => {
28
28
  await selectTransgenderStatus(page);
29
29
  await enterSedLedPssDates(page);
30
30
  await selectSentenceType(page);
31
- await selectSituationOption(page);
31
+ await selectAPPlacingReason(page);
32
32
  await selectReleaseDateKnownStatus(page);
33
33
  await confirmPlacementStartdate(page);
34
34
  await applicationOutsideNSTimescales(page);
@@ -1,10 +1,10 @@
1
1
  import { login, navigateToApplications } from "../login.mjs";
2
2
  import { enterCRN } from "./enter-crn.mjs";
3
3
  import { selectSentenceType } from "./select-sentence-type.mjs";
4
- import { selectSituationOption } from "./select-situation-option.mjs";
5
4
  import { selectReleaseDateKnownStatus } from "./release-date-known-status.mjs";
6
5
  import { confirmPlacementStartdate } from "./placement-start-date.mjs";
7
6
  import { selectAPPlacementPurpose } from "./ap-placement-purpose.mjs";
7
+ import { selectSituationOption } from "./select-situation-option.mjs";
8
8
  import { selectTypeOfAPRequired } from "./select-type-ap-required.mjs";
9
9
  import { enterSedLedPssDates, selectTransgenderStatus } from "./select-transgender-status.mjs";
10
10
  import { confirmYourDetails } from "./confirm-your-details.mjs";
@@ -6,6 +6,7 @@ import { faker } from "@faker-js/faker";
6
6
  async function submitCAS3Referral(page, crn) {
7
7
  await startApplication(page);
8
8
  await searchForPerson(page, crn);
9
+ await confirmPlacementLocation(page);
9
10
  await addOffenceAndBehaviourSummary(page);
10
11
  await addSentenceInformation(page);
11
12
  await enterContactDetails(page);
@@ -16,7 +17,6 @@ async function submitCAS3Referral(page, crn) {
16
17
  await enterPlacementConsiderations(page);
17
18
  await enterApprovalsForSpecificRisks(page);
18
19
  await outlineBehaviourInCAS(page);
19
- await confirmPlacementLocation(page);
20
20
  await addDisabilityCulturalAndSpecificNeeds(page);
21
21
  await addInformationOnSafeguardingAndSupport(page);
22
22
  await provideFoodAllergies(page);
@@ -248,11 +248,11 @@ async function outlineBehaviourInCAS(page) {
248
248
  }
249
249
  async function confirmPlacementLocation(page) {
250
250
  await page.getByRole("link", { name: "Confirm placement location" }).click();
251
- await expect(page).toHaveTitle(/Is placement required/);
252
- await page.getByRole("radio", {
253
- name: "No",
254
- exact: true
255
- }).check();
251
+ await expect(page).toHaveTitle(/Is the placement for the London region/);
252
+ await page.getByRole("radio", { name: "Yes, London" }).check();
253
+ await page.getByRole("button", { name: "Save and continue" }).click();
254
+ await expect(page).toHaveTitle(/Is placement required in a different PDU/);
255
+ await page.getByRole("radio", { name: "No" }).check();
256
256
  await page.getByRole("button", { name: "Save and continue" }).click();
257
257
  await expect(page).toHaveTitle("Make a referral for Transitional Accommodation (CAS3) - Transitional Accommodation (CAS3)");
258
258
  await expect(page.locator("#placement-location-status")).toHaveText("Completed");
@@ -1,6 +1,6 @@
1
1
  import { login, loginAsPrisonOfficer } from "./login.mjs";
2
2
  import { expect } from "@playwright/test";
3
- import { faker } from "@faker-js/faker";
3
+ import { faker } from "@faker-js/faker/locale/en_GB";
4
4
 
5
5
  //#region steps/cvl-licences/application.ts
6
6
  const createLicence = async (page, crn, nomsNumber) => {
@@ -16,13 +16,14 @@ const createLicence = async (page, crn, nomsNumber) => {
16
16
  await page.getByLabel(/Who is the initial appointment with?/).fill(faker.person.fullName());
17
17
  await page.getByRole("button", { name: "Continue" }).click();
18
18
  await expect(page).toHaveTitle("Create and vary a licence - Create a licence - Where is the initial appointment?");
19
- await page.getByLabel(/Building and street/).first().fill(faker.location.buildingNumber() + " " + faker.location.street());
19
+ await page.getByRole("link", { name: /Enter address manually/ }).click();
20
+ await page.getByLabel(/Address line 1/).first().fill(faker.location.buildingNumber() + " " + faker.location.street());
20
21
  await page.getByLabel(/Town or city/).fill(faker.location.city());
21
22
  await page.getByLabel("County (optional)").fill(faker.location.county());
22
23
  await page.getByLabel(/Postcode/).fill(faker.location.zipCode());
23
24
  await page.getByRole("button", { name: "Continue" }).click();
24
25
  await expect(page).toHaveTitle("Create and vary a licence - Create a licence - What is the contact phone number for the initial appointment?");
25
- await page.getByLabel("UK telephone number").fill(cvlFormattedPhoneNumber());
26
+ await page.getByLabel("UK telephone number").first().fill(cvlFormattedPhoneNumber());
26
27
  await page.getByRole("button", { name: "Continue" }).click();
27
28
  await expect(page).toHaveTitle("Create and vary a licence - Create a licence - When is the initial appointment?");
28
29
  await page.getByLabel(/Immediately after release/).check();
@@ -0,0 +1,6 @@
1
+ import { Page } from "@playwright/test";
2
+
3
+ //#region steps/delius/offender/delete-offender.d.ts
4
+ declare function deleteOffender(page: Page, crn: string): Promise<void>;
5
+ //#endregion
6
+ export { deleteOffender };
@@ -0,0 +1,15 @@
1
+ import { findOffenderByCRN } from "./find-offender.mjs";
2
+
3
+ //#region steps/delius/offender/delete-offender.ts
4
+ async function deleteOffender(page, crn) {
5
+ await findOffenderByCRN(page, crn);
6
+ await page.getByRole("link", { name: "Event List" }).click();
7
+ await page.getByRole("link", { name: "delete" }).click();
8
+ await page.getByRole("button", { name: "Confirm" }).click();
9
+ await page.getByRole("link", { name: "Personal Details" }).click();
10
+ await page.getByRole("button", { name: "Delete" }).click();
11
+ await page.getByRole("button", { name: "Confirm" }).click();
12
+ }
13
+
14
+ //#endregion
15
+ export { deleteOffender };
@@ -27,8 +27,8 @@ async function createRegistration(page, crn, registrationType, registeringOffice
27
27
  await doUntil(() => saveBtn.click(), () => expect(page.locator("tbody tr")).toContainText(registrationType));
28
28
  const tableRows = await page.$$("#registrationTable tbody tr");
29
29
  const [deliusRegtype, deliusRegDate, deliusRegNextReviewDate] = await Promise.all([
30
+ tableRows[0].$("td:nth-child(2)"),
30
31
  tableRows[0].$("td:nth-child(3)"),
31
- tableRows[0].$("td:nth-child(4)"),
32
32
  tableRows[0].$("td:nth-child(5)")
33
33
  ].map(async (cell) => {
34
34
  return cell ? await (await cell).innerText() : "";
@@ -0,0 +1,9 @@
1
+ import { Person } from "../delius/utils/person.mjs";
2
+ import { Page } from "@playwright/test";
3
+
4
+ //#region steps/esupervision/check-in.d.ts
5
+ declare function registerCase(page: Page, person: Person, crn: string): Promise<string>;
6
+ declare function createCheckin(page: Page, uuid: string, person: Person): Promise<void>;
7
+ declare function reviewCheckin(page: Page, person: Person): Promise<void>;
8
+ //#endregion
9
+ export { createCheckin, registerCase, reviewCheckin };
@@ -0,0 +1,70 @@
1
+ import { DeliusDateFormatter } from "../delius/utils/date-time.mjs";
2
+ import { login } from "../hmpps-auth/login.mjs";
3
+ import { expect } from "@playwright/test";
4
+ import { DateTime } from "luxon";
5
+
6
+ //#region steps/esupervision/check-in.ts
7
+ async function registerCase(page, person, crn) {
8
+ await login(page);
9
+ await page.goto(process.env.ESUPERVISION_URL);
10
+ await page.getByRole("button", { name: "Add person" }).click();
11
+ await enterPersonalDetails(page, person);
12
+ await page.getByRole("textbox", { name: /CRN/ }).fill(crn);
13
+ await page.getByRole("button", { name: "Continue" }).click();
14
+ await page.getByRole("link", { name: "Upload photo instead" }).click();
15
+ await page.locator("#photoUpload-input").setInputFiles("files/mock-person-photo.png");
16
+ await page.getByRole("button", { name: "Upload photo" }).click();
17
+ await page.getByRole("link", { name: "Yes, continue" }).click();
18
+ await page.getByRole("radio", { name: "Email" }).check();
19
+ await page.getByRole("button", { name: "Continue" }).click();
20
+ await page.locator("#email").fill(`simulate-delivered+${person.firstName}${person.lastName}@notifications.service.gov.uk`);
21
+ await page.getByRole("button", { name: "Continue" }).click();
22
+ await page.locator("#startDate").fill(DeliusDateFormatter(/* @__PURE__ */ new Date()));
23
+ await page.getByRole("radio", { name: "Every 8 weeks" }).check();
24
+ await page.getByRole("button", { name: "Continue" }).click();
25
+ await page.getByRole("button", { name: "Confirm and add person" }).click();
26
+ await page.getByRole("link", { name: "Awaiting check in" }).click();
27
+ const cell = page.getByRole("cell", {
28
+ name: person.firstName + " " + person.lastName,
29
+ exact: true
30
+ });
31
+ return await page.getByRole("row").filter({ has: cell }).getAttribute("data-checkin-uuid");
32
+ }
33
+ async function createCheckin(page, uuid, person) {
34
+ await page.goto(`${process.env.ESUPERVISION_URL}/submission/${uuid}`);
35
+ await page.getByRole("button", { name: "Start now" }).click();
36
+ await enterPersonalDetails(page, person);
37
+ await page.getByRole("button", { name: "Continue" }).click();
38
+ await page.getByRole("radio", { name: "Very well" }).check();
39
+ await page.getByRole("button", { name: "Continue" }).click();
40
+ await page.getByRole("checkbox", { name: "No, I do not need help" }).check();
41
+ await page.getByRole("button", { name: "Continue" }).click();
42
+ await page.getByRole("radio", { name: "No" }).check();
43
+ await page.getByRole("button", { name: "Continue" }).click();
44
+ await page.getByRole("button", { name: "Continue" }).click();
45
+ await page.getByRole("button", { name: "Start recording" }).click();
46
+ await page.getByRole("button", { name: "Submit video anyway" }).click();
47
+ await page.getByRole("checkbox", { name: /I confirm/ }).check();
48
+ await page.getByRole("button", { name: "Complete check in" }).click();
49
+ await expect(page.locator("h1")).toContainText("Check in completed");
50
+ }
51
+ async function enterPersonalDetails(page, person) {
52
+ await page.getByRole("textbox", { name: "First name" }).fill(person.firstName);
53
+ await page.getByRole("textbox", { name: "Last name" }).fill(person.lastName);
54
+ const dob = DateTime.fromJSDate(person.dob);
55
+ await page.getByRole("textbox", { name: "Day" }).fill(dob.day.toString());
56
+ await page.getByRole("textbox", { name: "Month" }).fill(dob.month.toString());
57
+ await page.getByRole("textbox", { name: "Year" }).fill(dob.year.toString());
58
+ }
59
+ async function reviewCheckin(page, person) {
60
+ await page.goto(process.env.ESUPERVISION_URL);
61
+ await page.getByRole("row").filter({ has: page.getByRole("cell", {
62
+ name: person.firstName + " " + person.lastName,
63
+ exact: true
64
+ }) }).getByRole("link", { name: /Review/ }).click();
65
+ await page.getByRole("radio", { name: "Yes" }).check();
66
+ await page.getByRole("button", { name: "Mark as reviewed" }).click();
67
+ }
68
+
69
+ //#endregion
70
+ export { createCheckin, registerCase, reviewCheckin };
@@ -9,7 +9,7 @@ const login = async (page) => {
9
9
  await page.click("#submit");
10
10
  await expect(page).toHaveTitle(/HMPPS Digital Services - Home/);
11
11
  await page.getByRole("link", { name: "Manage SOC Cases" }).click();
12
- await expect(page).toHaveTitle(/Manage SOC Cases/);
12
+ await expect(page).toHaveTitle(/Manage SOC cases/);
13
13
  };
14
14
 
15
15
  //#endregion
@@ -8,6 +8,8 @@ const referToSOC = async (page, crn) => {
8
8
  await page.getByRole("link", { name: "Add nominal to SOC" }).click();
9
9
  await page.getByLabel("Reason for referral or inclusion").fill("Automated testing");
10
10
  await page.getByRole("button", { name: "Save and continue" }).click();
11
+ await page.getByLabel("Directorate of Security (DoS").selectOption("North West and West Midlands");
12
+ await page.getByRole("button", { name: "Save and continue" }).click();
11
13
  await expect(page.getByRole("heading", { name: "Referral successful" })).toBeVisible();
12
14
  };
13
15
  function formatStaffNameForSOC(name) {
@@ -25,7 +25,6 @@ const allocateCase = async (page, crn, allocation) => {
25
25
  await page.getByRole("button", { name: "Continue" }).click();
26
26
  await refreshUntil(page, () => expect(page).toHaveTitle(/Review allocation notes/));
27
27
  await page.fill("#instructions", `${allocation.staff.firstName} ${allocation.staff.lastName} is allocated on case with ${crn}. Allocation for ${crn} completed by hmpps-end-to-end-tests`);
28
- await page.click("#isSensitive");
29
28
  await page.getByRole("button", { name: "Continue" }).click();
30
29
  await expect(page).toHaveURL(/spo-oversight-contact-option$/);
31
30
  await page.getByRole("button", { name: "Save my notes without editing" }).click();
@@ -59,8 +59,8 @@ const testEnvironmentData = {
59
59
  provider: "North East Region"
60
60
  },
61
61
  genericTeam: {
62
- name: "OMU A",
63
- provider: "NPS North East"
62
+ name: "Vale - Team",
63
+ provider: "Wales"
64
64
  }
65
65
  },
66
66
  prisoners: {