generated from ministryofjustice/hmpps-template-typescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MAN-19: Optimize Playwright Tests to Reduce Redundancy in Delius Veri…
…fication and Add Tests for Personal Details Match in MAS and Delius
- Loading branch information
smalepati99
committed
Sep 20, 2024
1 parent
82b1bf9
commit d16cd79
Showing
14 changed files
with
13,567 additions
and
4,066 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { Page } from '@playwright/test' | ||
import { | ||
Address, | ||
buildAddress, | ||
createAddress, | ||
} from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/address/create-address' | ||
|
||
const addAddress = async ( | ||
page: Page, | ||
crn: string, | ||
// eslint-disable-next-line default-param-last | ||
type: string = 'Main', | ||
tableId: string, | ||
): Promise<{ type: string; address: Address }> => { | ||
const address = buildAddress(type) | ||
await createAddress(page, crn, address) | ||
const addressType = await getTypeColumnValue(page, tableId) | ||
return { type: addressType, address } | ||
} | ||
|
||
const getTypeColumnValue = async (page: Page, tableId: string): Promise<string> => { | ||
const typeColumnIndex = await page.locator(`#${tableId} thead th:has-text("Type")`).evaluate(header => { | ||
const headers = Array.from(header.parentElement.children) | ||
return headers.indexOf(header) + 1 | ||
}) | ||
return page.locator(`#${tableId} tbody tr:first-child td:nth-child(${typeColumnIndex})`).innerText() | ||
} | ||
|
||
export default addAddress |
31 changes: 31 additions & 0 deletions
31
e2e_tests/steps/delius/add-personal-details/addPersonalDetails.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { faker } from '@faker-js/faker/locale/en_GB' | ||
import { Page, expect } from '@playwright/test' | ||
import { findOffenderByCRN } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/offender/find-offender' | ||
import { retryOnError } from '../utils/utils' | ||
|
||
interface PersonalDetails { | ||
mobileNumber: string | ||
telephoneNumber: string | ||
email: string | ||
} | ||
|
||
const addPersonalDetails = async (page: Page, crn: string): Promise<PersonalDetails> => { | ||
return retryOnError(async innerPage => { | ||
await findOffenderByCRN(innerPage, crn) | ||
await innerPage.locator('#navigation-include\\:linkNavigation2OffenderIndex').click() | ||
await innerPage.getByRole('link', { name: 'Personal Details' }).click() | ||
await innerPage.getByRole('button', { name: 'Update' }).click() | ||
await expect(innerPage.locator('#content > h1')).toContainText('Update Personal Details') | ||
await innerPage.getByLabel('Mobile Number:').fill(`07${faker.string.numeric(9)}`) | ||
await innerPage.getByLabel('Telephone Number:').fill(faker.phone.number()) | ||
await innerPage.getByLabel('Email address:').fill(faker.internet.email()) | ||
await innerPage.getByRole('button', { name: 'Save' }).click() | ||
await expect(innerPage.locator('#content > h1')).toContainText('Personal Details') | ||
const mobileNumber = await innerPage.locator('#Mobile\\:outputText').textContent() | ||
const telephoneNumber = await innerPage.locator('#Telephone\\:outputText').textContent() | ||
const email = await innerPage.locator('#Email\\:outputText').textContent() | ||
return { mobileNumber, telephoneNumber, email } | ||
}, page) | ||
} | ||
|
||
export default addPersonalDetails |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Page } from '@playwright/test' | ||
import { login as loginToDelius } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/login' | ||
import { | ||
deliusPerson, | ||
Person, | ||
} from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/utils/person' | ||
import { createOffender } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/offender/create-offender' | ||
|
||
const loginDeliusAndCreateOffender = async (page: Page): Promise<[Person, string]> => { | ||
await loginToDelius(page) | ||
const person = deliusPerson() | ||
const crn = await createOffender(page, { person }) | ||
return [person, crn] | ||
} | ||
|
||
export default loginDeliusAndCreateOffender |
45 changes: 45 additions & 0 deletions
45
e2e_tests/steps/delius/create-personal-contact/createPersonalContact.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { Page, expect } from '@playwright/test' | ||
import { faker } from '@faker-js/faker/locale/en_GB' | ||
import { selectOption } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/utils/inputs' | ||
import { Address } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/address/create-address' | ||
import { findOffenderByCRN } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/offender/find-offender' | ||
import { formatDate, retryOnError } from '../utils/utils' | ||
|
||
export const createPersonalContact = async (page: Page, crn: string, options: Address) => { | ||
return retryOnError(async innerPage => { | ||
await findOffenderByCRN(innerPage, crn) // Use innerPage instead of page | ||
await innerPage.locator('#navigation-include\\:linkNavigation2OffenderIndex').click() | ||
const firstName = faker.person.firstName() | ||
const lastName = faker.person.lastName() | ||
const contactName = `${firstName} ${lastName}` | ||
const contactPhoneNumber = `07${faker.string.numeric(9)}` | ||
const contactEmail = faker.internet.email() | ||
const notes = `Added Emergency contact on ${formatDate(new Date())}` | ||
await innerPage.locator('#navigation-include\\:linkNavigation3PersonalContact').click() | ||
await expect(innerPage).toHaveTitle('Personal Contacts') | ||
await innerPage.locator('[value="Add Personal Contact"]').click() | ||
await expect(innerPage).toHaveTitle('Add Personal Contact') | ||
await selectOption(innerPage, '#Relationship\\:selectOneMenu', 'Emergency Contact') | ||
await innerPage.locator('#RelationshipToOffender\\:inputText').fill('Friend') | ||
await innerPage.locator('#FirstName\\:inputText').fill(firstName) | ||
await innerPage.locator('#Surname\\:inputText').fill(lastName) | ||
await innerPage.locator('#MobileNumber\\:inputText').fill(contactPhoneNumber) | ||
await innerPage.locator('#EmailAddress\\:inputText').fill(contactEmail) | ||
await innerPage.locator('#Notes\\:notesField').fill(notes) | ||
await innerPage.locator('#HouseNumber\\:inputText').fill(options.buildingNumber) | ||
await innerPage.locator('#StreetName\\:inputText').fill(options.street) | ||
await innerPage.locator('#TownCity\\:inputText').fill(options.cityName) | ||
await innerPage.locator('#County\\:inputText').fill(options.county) | ||
await innerPage.locator('#Postcode\\:inputText').fill(options.zipCode) | ||
await innerPage.locator('[value="Save"]').click() | ||
await expect(innerPage).toHaveTitle('Personal Contacts') | ||
|
||
return { | ||
contactName, | ||
contactPhoneNumber, | ||
contactEmail, | ||
} | ||
}, page) // Pass the page object to retryOnError | ||
} | ||
|
||
export default createPersonalContact |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Page } from '@playwright/test' | ||
import { DateTime } from 'luxon' | ||
|
||
export const retryOnError = async <T>( | ||
fn: (page: Page) => Promise<T>, | ||
page: Page, | ||
retryOnErrorPage = true, | ||
): Promise<T> => { | ||
try { | ||
return await fn(page) | ||
} catch (error) { | ||
if (retryOnErrorPage && (await page.title()) === 'Error Page') { | ||
return fn(page) | ||
} | ||
throw error | ||
} | ||
} | ||
|
||
export const formatDate = date => DateTime.fromJSDate(date).toFormat('d MMMM yyyy') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Page, expect, Locator } from '@playwright/test' | ||
import { login as loginToManageMySupervision } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/manage-a-supervision/login' | ||
|
||
export const loginMasAndGoToPersonalDetails = async (page: Page, crn: string) => { | ||
await loginToManageMySupervision(page) | ||
await searchForCrn(page, crn) | ||
await page.getByRole('link', { name: 'Personal details' }).first().click() | ||
await expect(page.locator('h1.govuk-heading-l')).toContainText('Personal Details') | ||
} | ||
|
||
export const searchForCrn = async (page: Page, crn: string) => { | ||
await page.getByRole('link', { name: 'Search' }).click() | ||
await page.getByLabel('Find a person on probation').fill(crn) | ||
await page.getByRole('button', { name: 'Search' }).click() | ||
await page.locator(`[href$="${crn}"]`).click() | ||
await expect(page).toHaveTitle('Manage a Supervision - Overview') | ||
} | ||
|
||
export const assertAddressDetails = async ( | ||
page: Page, | ||
locator: Locator, | ||
address: { buildingNumber: string; street: string; cityName: string; county: string; zipCode: string }, | ||
) => { | ||
await expect(locator).toContainText(`${address.buildingNumber} ${address.street}`) | ||
await expect(locator).toContainText(address.cityName) | ||
await expect(locator).toContainText(address.county) | ||
await expect(locator).toContainText(address.zipCode) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import { Browser, BrowserContext, expect, Page, test } from '@playwright/test' | ||
import * as dotenv from 'dotenv' | ||
import { Person } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/utils/person.js' | ||
import { | ||
buildAddress, | ||
Address, | ||
} from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/delius/address/create-address' | ||
import { login as loginToManageMySupervision } from '@ministryofjustice/hmpps-probation-integration-e2e-tests/steps/manage-a-supervision/login.js' | ||
import loginDeliusAndCreateOffender from '../steps/delius/create-offender/createOffender' | ||
|
||
import addPersonalDetails from '../steps/delius/add-personal-details/addPersonalDetails' | ||
import { createPersonalContact } from '../steps/delius/create-personal-contact/createPersonalContact' | ||
import addAddress from '../steps/delius/add-address/addAddress' | ||
import { | ||
assertAddressDetails, | ||
loginMasAndGoToPersonalDetails, | ||
searchForCrn, | ||
} from '../steps/mas/personal-details/personalDetails' | ||
import { formatDate } from '../steps/delius/utils/utils' | ||
|
||
dotenv.config({ path: 'e2e_tests/.env' }) // read environment variables into process.env | ||
|
||
const todaysDate = formatDate(new Date()) | ||
|
||
let crn: string | ||
let person: Person | ||
let mobileNumber: string | ||
let telephoneNumber: string | ||
let email: string | ||
let mainAddressType: string | ||
let mainAddress: Address | ||
let addressType: string | ||
let otherAddress: Address | ||
let contactName: string | ||
let contactPhoneNumber: string | ||
let contactEmail: string | ||
let contactAddress: Address | ||
|
||
// Create a context and page manually for beforeAll | ||
let browser: Browser | ||
let context: BrowserContext | ||
let page: Page | ||
|
||
test.describe('Delius Details Verification', () => { | ||
test.beforeAll(async ({ browser: b }) => { | ||
test.setTimeout(120000) | ||
browser = b | ||
context = await browser.newContext() | ||
page = await context.newPage() | ||
|
||
// Log in to Delius and create a new person record | ||
;[person, crn] = await loginDeliusAndCreateOffender(page) | ||
|
||
// Add personal details, main address, secondary address, and personal contact details | ||
;({ mobileNumber, telephoneNumber, email } = await addPersonalDetails(page, crn)) | ||
;({ type: mainAddressType, address: mainAddress } = await addAddress(page, crn, 'Main', 'mainAddressTable')) | ||
;({ type: addressType, address: otherAddress } = await addAddress(page, crn, 'Secondary', 'otherAddressTable')) | ||
|
||
// Initialize contactAddress | ||
contactAddress = buildAddress() | ||
;({ contactName, contactPhoneNumber, contactEmail } = await createPersonalContact(page, crn, contactAddress)) | ||
}) | ||
|
||
test.afterAll(async () => { | ||
// Close the context only after all tests have completed | ||
await context.close() | ||
}) | ||
|
||
test('Verify the header details', async ({ page: innerPage }) => { | ||
// Login to MaS and search for Crn | ||
await loginToManageMySupervision(innerPage) | ||
await searchForCrn(innerPage, crn) | ||
|
||
// Verify the person appears in the search results and crn, name, dob & tier matches | ||
await expect(innerPage.getByTestId('crn')).toContainText(crn) | ||
await expect(innerPage.getByTestId('name')).toContainText(`${person.firstName} ${person.lastName}`) | ||
await expect(innerPage.getByTestId('headerDateOfBirthValue')).toContainText(formatDate(person.dob)) | ||
await expect(innerPage.getByTestId('tierValue').first()).toContainText('D0') | ||
}) | ||
|
||
test('Verify that the personal details of a person in MAS match those in Delius', async ({ page: innerPage }) => { | ||
// Login to MaS and search for Crn | ||
await loginMasAndGoToPersonalDetails(innerPage, crn) | ||
|
||
// Verify that the personal details match those in Delius | ||
await Promise.all([ | ||
expect(innerPage.getByTestId('telephoneNumberValue')).toContainText(telephoneNumber), | ||
expect(innerPage.getByTestId('mobileNumberValue')).toContainText(mobileNumber), | ||
expect(innerPage.getByTestId('emailAddressValue')).toContainText(email), | ||
]) | ||
|
||
// Verify that the main address details match those in Delius | ||
await innerPage.getByText('View address details').click() | ||
await Promise.all([ | ||
assertAddressDetails(innerPage, innerPage.getByTestId('mainAddressValue'), mainAddress), | ||
expect(innerPage.getByTestId('addressTypeValue')).toContainText(`${mainAddressType} (verified)`), | ||
expect(innerPage.getByTestId('mainAddressStartDateValue')).toContainText(todaysDate), | ||
expect(innerPage.getByTestId('mainAddressNotesValue')).toContainText('Notes added for Main address'), | ||
]) | ||
|
||
// Verify secondary address details match those in Delius | ||
await innerPage.getByRole('link', { name: /View all addresses/ }).click() | ||
await expect(innerPage.locator('h1')).toContainText('Addresses') | ||
await Promise.all([ | ||
assertAddressDetails(innerPage, innerPage.getByTestId('otherAddressValue1'), otherAddress), | ||
expect(innerPage.getByTestId('otherAddressTypeValue1')).toContainText(`${addressType} (verified)`), | ||
expect(innerPage.getByTestId('otherAddressStartDateValue1')).toContainText(todaysDate), | ||
expect(innerPage.getByTestId('otherAddressNotesValue1')).toContainText('Notes added for Secondary address'), | ||
]) | ||
|
||
// Verify that the emergency contact details match those in Delius | ||
await innerPage.getByRole('link', { name: 'Personal details' }).first().click() | ||
await innerPage.getByRole('link', { name: `${contactName} – ` }).click() | ||
await Promise.all([ | ||
expect(innerPage.getByTestId('contactRelationshipTypeHeaderValue')).toContainText('Emergency Contact'), | ||
expect(innerPage.getByTestId('contactNameValue')).toContainText(contactName), | ||
expect(innerPage.getByTestId('contactRelationshipValue')).toContainText('Friend'), | ||
assertAddressDetails(innerPage, innerPage.getByTestId('contactAddressValue'), contactAddress), | ||
expect(innerPage.getByTestId('contactPhoneValue')).toContainText(contactPhoneNumber), | ||
expect(innerPage.getByTestId('contactEmailValue')).toContainText(contactEmail), | ||
expect(innerPage.getByTestId('contactStartDateValue')).toContainText(todaysDate), | ||
expect(innerPage.getByTestId('contactNotesValue')).toContainText(`Added Emergency contact on ${todaysDate}`), | ||
]) | ||
}) | ||
}) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.