diff --git a/e2e/helpers.ts b/e2e/helpers.ts index bff40e4e9..ea564b260 100644 --- a/e2e/helpers.ts +++ b/e2e/helpers.ts @@ -1,5 +1,5 @@ import { Locator, Page, expect } from '@playwright/test' -import { AUTH_URL, CLIENT_URL } from './constants' +import { AUTH_URL, CLIENT_URL, GATEWAY_HOST } from './constants' export async function login(page: Page, username: string, password: string) { const token = await getToken(username, password) @@ -112,6 +112,12 @@ export const uploadImage = async ( await fileChooser.setFiles(image) } +export const getLocationNameFromFhirId = async (fhirId: string) => { + const res = await fetch(`${GATEWAY_HOST}/location/${fhirId}`) + const location = (await res.json()) as fhir.Location + return location.name +} + export async function continueForm(page: Page) { /* * This timeout is to ensure that all previous actions have been completed diff --git a/e2e/testcases/applications/.gitkeep b/e2e/testcases/applications/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/e2e/testcases/applications/17-validate-user-can-correct-a-record-from-audit-record-page.spec.ts b/e2e/testcases/applications/17-validate-user-can-correct-a-record-from-audit-record-page.spec.ts new file mode 100644 index 000000000..2874688e4 --- /dev/null +++ b/e2e/testcases/applications/17-validate-user-can-correct-a-record-from-audit-record-page.spec.ts @@ -0,0 +1,102 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../helpers' +import faker from '@faker-js/faker' +import { createDeclaration } from '../birth/helpers' +import TEST_DATA_1 from '../birth/data/1-both-mother-and-father.json' + +test.describe + .serial('17. Validate user can correct a record from audit record page', () => { + let page: Page + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + test('17.0 Create Declaration', async () => { + const token = await getToken('k.mweene', 'test') + const res = await createDeclaration(token, { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: TEST_DATA_1['Child details'].Sex.toLowerCase() as 'male' + }, + informant: { + type: TEST_DATA_1['Informant details'][ + 'Relationship to child' + ].toUpperCase() as 'MOTHER' + }, + attendant: { + type: TEST_DATA_1['Child details'][ + 'Attendant at birth' + ].toUpperCase() as 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + }) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + }) + + test('17.1 Go to ready to print tab > search for a certified record > click any application not downloaded', async () => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByRole('button', { name: 'Ready to print' }).click() + await page.locator('#name_0').click() + + /* + * Expected result: should + * - Navigate to record audit page + * - Not show correct recort optoin + * - Print button should be disabled + */ + await expect( + page.getByRole('button', { name: 'Correct record' }) + ).not.toBeVisible() + await expect( + page.getByRole('button', { name: 'Print', exact: true }) + ).toBeDisabled() + expect(page.url().includes('record-audit')) + }) + + test('17.2 Click download > click assign', async () => { + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should + * - Show correct recort optoin + * - Print button should not be disabled + */ + await expect( + page.getByRole('button', { name: 'Correct record' }) + ).toBeVisible() + await expect( + page.getByRole('button', { name: 'Print', exact: true }) + ).not.toBeDisabled() + }) + + test('17.3 Click "Correct record"', async () => { + await page.getByRole('button', { name: 'Correct record' }).click() + + /* + * Expected result: should show correct record page + */ + await expect( + page.getByRole('heading', { name: 'Correct record' }) + ).toBeVisible() + expect(page.url().includes('correction')) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-1.spec.ts b/e2e/testcases/applications/correction/correct-record-1.spec.ts new file mode 100644 index 000000000..8b8c18166 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-1.spec.ts @@ -0,0 +1,960 @@ +import { expect, test, type Page } from '@playwright/test' +import { + createPIN, + getLocationNameFromFhirId, + getToken, + login, + uploadImage +} from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe('1. Correct record - 1', () => { + let declaration: BirthDeclaration + let trackingId = '' + + const updatedChildDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + gender: 'Female', + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random())), + 'yyyy-MM-dd' + ), + placeOfBirth: 'Tembwe Rural Health Centre', + attendantAtBirth: 'Nurse', + typeOfBirth: 'Twin', + weightAtBirth: '3.1' + } + + test.beforeAll(async () => { + let token = await getToken('k.mweene', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('f.katongo', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test.describe('1.1 Validate verbiage', async () => { + test.beforeEach(async ({ page }) => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + }) + + test('1.1.1 Validate record audit page', async ({ page }) => { + /* + * Expected result: should + * - See in header child's name and correct record option + * - Navigate to record audit page + * - See status, event, trackingId, BRN, DOB, Place of birth, Informant contact + */ + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + await expect( + page.getByRole('button', { name: 'Correct record' }) + ).toBeVisible() + + expect(page.url().includes('record-audit')).toBeTruthy() + + await expect( + page.getByText(`Status${declaration.registration.status[0].type}`) + ).toBeVisible() + await expect( + page.getByText(`Event${declaration.registration.type}`) + ).toBeVisible() + await expect(page.getByText(`Tracking ID${trackingId}`)).toBeVisible() + await expect( + page.getByText( + `Registration No${declaration.registration.registrationNumber}` + ) + ).toBeVisible() + await expect( + page.getByText(`Date of birth${format( + parseISO(declaration.child.birthDate), + 'MMMM dd, yyyy' + )} + `) + ).toBeVisible() + // await expect(page.getByText(`Place of birth${}`)).toBeVisible() + await expect( + page.getByText(declaration.registration.contactEmail) + ).toBeVisible() + }) + + test('1.1.2 Validate correction requester page', async ({ page }) => { + await page.getByRole('button', { name: 'Correct record' }).click() + + /* + * Expected result: should + * - Navigate to Correction Requester Page + */ + await expect(page.getByText('Correction requester')).toBeVisible() + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('corrector')).toBeTruthy() + + /* + * Expected result: should say + * - Note: In the case that the child is now of legal age (18) then only they should be able to request a change to their birth record. + */ + await expect( + page.getByText( + 'Note: In the case that the child is now of legal age (18) then only they should be able to request a change to their birth record.' + ) + ).toBeVisible() + }) + + test('1.1.3 Validate identity verification page for Mother', async ({ + page + }) => { + await page.getByRole('button', { name: 'Correct record' }).click() + + await page.getByLabel('Mother').check() + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should show + * Text: Verify their identity + * Button: Verified + * Button: Identity does not match + */ + await expect(page.getByText('Verify their identity')).toBeVisible() + await expect(page.getByRole('button', { name: 'Verified' })).toBeVisible() + await expect( + page.getByRole('button', { name: 'Identity does not match' }) + ).toBeVisible() + + /* + * Expected result: should Confirm + * ID + * First Name + * Last Name + * Date of Birth + * Nationality + */ + await expect( + page.getByText( + `ID: National Id | ${declaration.mother.identifier[0].id}` + ) + ).toBeVisible() + await expect( + page.getByText( + `First name(s): ${declaration.mother.name[0].firstNames}` + ) + ).toBeVisible() + await expect( + page.getByText(`Last name: ${declaration.mother.name[0].familyName}`) + ).toBeVisible() + await expect( + page.getByText( + `Date of Birth: + ${format(parseISO(declaration.mother.birthDate), 'dd MMMM yyyy')} + ` + ) + ).toBeVisible() + await expect( + page.getByText(`Nationality: ${declaration.mother.nationality}`) + ).toBeVisible() + }) + }) + + test.describe.serial('1.2 Record correction by mother', async () => { + let page: Page + + let childBirthLocationName: string | undefined + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Correct record' }).click() + + await page.getByLabel('Mother').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + test.afterAll(async () => { + await page.close() + }) + + test('1.2.1 Verify identity', async () => { + await page.getByRole('button', { name: 'Verified' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('1.2.2 Correction made on child details', async () => { + test('1.2.2.1 Change name', async () => { + await page + .locator('#child-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page + .locator('#firstNamesEng') + .fill(updatedChildDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedChildDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#child-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.child.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.child.name[0].familyName + ) + + await expect( + page + .locator('#child-content #Full') + .getByText(updatedChildDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#child-content #Full') + .getByText(updatedChildDetails.familyName) + ).toBeVisible() + }) + + test('1.2.2.2 Change gender', async () => { + await page + .locator('#child-content #Sex') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#gender')).toBeTruthy() + + await page.locator('#gender').click() + await page.getByText(updatedChildDetails.gender).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#child-content #Sex').getByRole('deletion') + ).toHaveText(declaration.child.gender, { ignoreCase: true }) + + await expect( + page + .locator('#child-content #Sex') + .getByText(updatedChildDetails.gender) + ).toBeVisible() + }) + + test('1.2.2.3 Change date of birth', async () => { + await page + .locator('#child-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#childBirthDate')).toBeTruthy() + + const birthDay = updatedChildDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#child-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.child.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#child-content #Date') + .getByText( + format(parseISO(updatedChildDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('1.2.2.4 Change place of delivery', async () => { + await page + .locator('#child-content #Place') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's place of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#placeOfBirth')).toBeTruthy() + + await page + .locator('#birthLocation') + .fill(updatedChildDetails.placeOfBirth.slice(0, 2)) + await page.getByText(updatedChildDetails.placeOfBirth).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous place of birth with strikethrough + * - show updated place of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.eventLocation).toBeDefined() + + childBirthLocationName = await getLocationNameFromFhirId( + declaration.eventLocation!.id + ) + expect(childBirthLocationName).toBeDefined() + + await expect( + page.locator('#child-content #Place').getByRole('deletion').nth(1) + ).toHaveText(childBirthLocationName!, { + ignoreCase: true + }) + + await expect( + page + .locator('#child-content #Place') + .getByText(updatedChildDetails.placeOfBirth) + ).toBeVisible() + }) + + test('1.2.2.5 Change attendant at birth', async () => { + await page + .locator('#child-content #Attendant') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's Attendant at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#attendantAtBirth')).toBeTruthy() + + await page.locator('#attendantAtBirth').click() + await page.getByText(updatedChildDetails.attendantAtBirth).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Attendant at birth with strikethrough + * - show updated Attendant at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.attendantAtBirth).toBeDefined + + await expect( + page.locator('#child-content #Attendant').getByRole('deletion') + ).toHaveText(declaration.attendantAtBirth!, { ignoreCase: true }) + + await expect( + page + .locator('#child-content #Attendant') + .getByText(updatedChildDetails.attendantAtBirth) + ).toBeVisible() + }) + + test('1.2.2.6 Change type of birth', async () => { + await page + .locator('#child-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's type of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#birthType')).toBeTruthy() + + await page.locator('#birthType').click() + await page.getByText(updatedChildDetails.typeOfBirth).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous type of birth with strikethrough + * - show updated type of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.birthType).toBeDefined + + await expect( + page.locator('#child-content #Type').getByRole('deletion') + ).toHaveText(declaration.birthType!, { ignoreCase: true }) + + await expect( + page + .locator('#child-content #Type') + .getByText(updatedChildDetails.typeOfBirth) + ).toBeVisible() + }) + + test('1.2.2.7 Change weight at birth', async () => { + await page + .locator('#child-content #Weight') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's weight at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#weightAtBirth')).toBeTruthy() + + await page + .locator('#weightAtBirth') + .fill(updatedChildDetails.weightAtBirth) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous weight at birth with strikethrough + * - show updated weight at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.weightAtBirth).toBeDefined + + await expect( + page.locator('#child-content #Weight').getByRole('deletion') + ).toHaveText(declaration.weightAtBirth! + ' kilograms (kg)') + + await expect( + page + .locator('#child-content #Weight') + .getByText(updatedChildDetails.weightAtBirth + ' kilograms (kg)') + ).toBeVisible() + }) + }) + + test('1.2.3 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Continue' }) + ).toBeDisabled() + + await page.getByText('Select...').click() + await page.getByText('Affidavit', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Court Document', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Other', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('1.2.4 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Continue' }) + ).toBeDisabled() + + await page + .getByLabel('Myself or an agent made a mistake (Clerical error)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('1.2.5 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Send for approval button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Send for approval' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Child)' + + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + + updatedChildDetails.firstNames + + ' ' + + updatedChildDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Child)' + declaration.child.gender + updatedChildDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Child)' + + format(parseISO(declaration.child.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedChildDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Place of delivery (Child)' + + 'Health Institution' + + childBirthLocationName + + 'Health Institution' + + updatedChildDetails.placeOfBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Attendant at birth (Child)' + + declaration.attendantAtBirth + + updatedChildDetails.attendantAtBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of birth (Child)' + + declaration.birthType + + updatedChildDetails.typeOfBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Weight at birth (Child)' + + declaration.weightAtBirth + + updatedChildDetails.weightAtBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + declaration.mother.name[0].firstNames + + ' ' + + declaration.mother.name[0].familyName + ) + ).toBeVisible() + await expect(page.getByText('Verified')).toBeVisible() + await expect( + page.getByText('Myself or an agent made a mistake (Clerical error)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('Yes').check() + await page + .locator('#correctionFees\\.nestedFields\\.totalFees') + .fill('15') + + await uploadImage(page, page.locator('#upload_document')) + + /* + * Expected result: should enable the Send for approval button + */ + await page.getByRole('button', { name: 'Send for approval' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should + * - be navigated to sent for approval tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/approvals')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + + test.describe('1.2.6 Correction Approval', async () => { + test.beforeAll(async ({ browser }) => { + await page.close() + page = await browser.newPage() + + await login(page, 'k.mweene', 'test') + await createPIN(page) + }) + + test('1.2.6.1 Record audit by local registrar', async () => { + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + await page.locator('#name_0').click() + }) + + test('1.2.6.2 Correction review', async () => { + await page.getByRole('button', { name: 'Review', exact: true }).click() + + /* + * Expected result: should show + * - Submitter + * - Requested by + * - Reason for request + * - Comments + * - Original vs correction + */ + + await expect( + page.getByText('Submitter' + 'Felix Katongo') + ).toBeVisible() + + await expect( + page.getByText( + 'Requested by' + + declaration.mother.name[0].firstNames + + ' ' + + declaration.mother.name[0].familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Reason for request' + + 'Myself or an agent made a mistake (Clerical error)' + ) + ).toBeVisible() + await expect( + page.getByText( + 'Comments' + declaration.registration.registrationNumber + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (Child)' + + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + + updatedChildDetails.firstNames + + ' ' + + updatedChildDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Child)' + + declaration.child.gender + + updatedChildDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Child)' + + format(parseISO(declaration.child.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedChildDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Place of delivery (Child)' + + 'Health Institution' + + childBirthLocationName + + 'Health Institution' + + updatedChildDetails.placeOfBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Attendant at birth (Child)' + + declaration.attendantAtBirth + + updatedChildDetails.attendantAtBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of birth (Child)' + + declaration.birthType + + updatedChildDetails.typeOfBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Weight at birth (Child)' + + declaration.weightAtBirth + + updatedChildDetails.weightAtBirth + ) + ).toBeVisible() + }) + + test('1.2.6.3 Approve correction', async () => { + await page.getByRole('button', { name: 'Approve', exact: true }).click() + await page.getByRole('button', { name: 'Confirm', exact: true }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the updated declaration in this tab + */ + expect(page.url().includes('registration-home/print')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText( + '1', + { + timeout: 1000 * 30 + } + ) + await expect( + page.getByText( + updatedChildDetails.firstNames + + ' ' + + updatedChildDetails.familyName + ) + ).toBeVisible() + }) + test('1.2.6.4 Validate history in record audit', async () => { + await page + .getByText( + updatedChildDetails.firstNames + + ' ' + + updatedChildDetails.familyName + ) + .click() + + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Correction requested + * - Correction approved + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction requested' }) + ).toBeVisible() + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction approved' }) + ).toBeVisible() + }) + }) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-10.spec.ts b/e2e/testcases/applications/correction/correct-record-10.spec.ts new file mode 100644 index 000000000..b246cc746 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-10.spec.ts @@ -0,0 +1,1141 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login, uploadImage } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' +import { DeathDeclaration } from '../../death/types' + +test.describe('10. Correct record - 10', () => { + let declaration: DeathDeclaration + let trackingId = '' + + const updatedDeceasedDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + gender: 'Female', + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random()) + 365 * 25), + 'yyyy-MM-dd' + ), + nationality: 'Canada', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Pualula', + district: 'Pili', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + NOdependants: '3' + } + + test.beforeAll(async () => { + let token = await getToken('k.mweene', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('f.katongo', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test.describe('10.1 Validate verbiage', async () => { + test.beforeEach(async ({ page }) => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + }) + + test('10.1.1 Validate record audit page', async ({ page }) => { + /* + * Expected result: should + * - See in header deceased's name and correct record option + * - Navigate to record audit page + * - See status, event, trackingId, BRN, DOB, Place of birth, Informant contact + */ + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + await expect( + page.getByRole('button', { name: 'Correct record' }) + ).toBeVisible() + + expect(page.url().includes('record-audit')).toBeTruthy() + + await expect( + page.getByText(`Status${declaration.registration.status[0].type}`) + ).toBeVisible() + await expect( + page.getByText(`Event${declaration.registration.type}`) + ).toBeVisible() + await expect(page.getByText(`Tracking ID${trackingId}`)).toBeVisible() + await expect( + page.getByText( + `Registration No${declaration.registration.registrationNumber}` + ) + ).toBeVisible() + await expect( + page.getByText(`Date of death${format( + parseISO(declaration.deceased.deceased.deathDate), + 'MMMM dd, yyyy' + )} + `) + ).toBeVisible() + // await expect(page.getByText(`Place of birth${}`)).toBeVisible() + await expect( + page.getByText(declaration.registration.contactEmail) + ).toBeVisible() + }) + + test('10.1.2 Validate correction requester page', async ({ page }) => { + await page.getByRole('button', { name: 'Correct record' }).click() + + /* + * Expected result: should + * - Navigate to Correction Requester Page + */ + await expect(page.getByText('Correction requester')).toBeVisible() + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('corrector')).toBeTruthy() + }) + + test('10.1.3 Validate identity verification page for Informant (SPOUSE)', async ({ + page + }) => { + await page.getByRole('button', { name: 'Correct record' }).click() + + await page.getByLabel('Informant (SPOUSE)').check() + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should show + * Text: Verify their identity + * Button: Verified + * Button: Identity does not match + */ + await expect(page.getByText('Verify their identity')).toBeVisible() + await expect(page.getByRole('button', { name: 'Verified' })).toBeVisible() + await expect( + page.getByRole('button', { name: 'Identity does not match' }) + ).toBeVisible() + + /* + * Expected result: should Confirm + * ID + * First Name + * Last Name + * Date of Birth + * Nationality + */ + await expect( + page.getByText( + `ID: National Id | ${declaration.informant.identifier[0].id}` + ) + ).toBeVisible() + await expect( + page.getByText( + `First name(s): ${declaration.informant.name[0].firstNames}` + ) + ).toBeVisible() + await expect( + page.getByText(`Last name: ${declaration.informant.name[0].familyName}`) + ).toBeVisible() + await expect( + page.getByText( + `Date of Birth: + ${format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy')} + ` + ) + ).toBeVisible() + await expect( + page.getByText(`Nationality: ${declaration.informant.nationality}`) + ).toBeVisible() + }) + }) + + test.describe.serial('10.2 Record correction by informant', async () => { + let page: Page + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Correct record' }).click() + + await page.getByLabel('Informant (SPOUSE)').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + test.afterAll(async () => { + await page.close() + }) + + test('10.2.1 Verify identity', async () => { + /* + * Expected result: should Confirm + * ID + * First Name + * Last Name + * Date of Birth + * Nationality + */ + await expect( + page.getByText( + `ID: National Id | ${declaration.informant.identifier[0].id}` + ) + ).toBeVisible() + await expect( + page.getByText( + `First name(s): ${declaration.informant.name[0].firstNames}` + ) + ).toBeVisible() + await expect( + page.getByText(`Last name: ${declaration.informant.name[0].familyName}`) + ).toBeVisible() + await expect( + page.getByText( + `Date of Birth: + ${format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy')} + ` + ) + ).toBeVisible() + await expect( + page.getByText(`Nationality: ${declaration.informant.nationality}`) + ).toBeVisible() + + await page.getByRole('button', { name: 'Verified' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('10.2.2 Correction made on deceased details', async () => { + test('10.2.2.1 Change name', async () => { + await page + .locator('#deceased-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page + .locator('#firstNamesEng') + .fill(updatedDeceasedDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedDeceasedDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#deceased-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.deceased.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.deceased.name[0].familyName + ) + + await expect( + page + .locator('#deceased-content #Full') + .getByText(updatedDeceasedDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Full') + .getByText(updatedDeceasedDetails.familyName) + ).toBeVisible() + }) + + test('10.2.2.2 Change gender', async () => { + await page + .locator('#deceased-content #Sex') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#gender')).toBeTruthy() + + await page.locator('#gender').click() + await page.getByText(updatedDeceasedDetails.gender).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Sex').getByRole('deletion') + ).toHaveText(declaration.deceased.gender, { ignoreCase: true }) + + await expect( + page + .locator('#deceased-content #Sex') + .getByText(updatedDeceasedDetails.gender) + ).toBeVisible() + }) + + test('10.2.2.3 Change date of birth', async () => { + await page + .locator('#deceased-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedBirthDate')).toBeTruthy() + + const birthDay = updatedDeceasedDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#deceased-content #Date') + .getByText( + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('10.2.2.4 Change nationality', async () => { + await page + .locator('#deceased-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedDeceasedDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#deceased-content #Nationality') + .getByText(updatedDeceasedDetails.nationality) + ).toBeVisible() + }) + + test('10.2.2.5 Change id type', async () => { + await page + .locator('#deceased-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedIdType')).toBeTruthy() + + await page.locator('#deceasedIdType').click() + await page.getByText(updatedDeceasedDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#deceased-content #Type') + .getByText(updatedDeceasedDetails.idType) + ).toBeVisible() + }) + + test('10.2.2.6 Change id', async () => { + await page + .locator('#deceased-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedPassport')).toBeTruthy() + + await page.locator('#deceasedPassport').fill(updatedDeceasedDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#deceased-content #ID') + .getByText(updatedDeceasedDetails.id) + ).toBeVisible() + }) + + test('10.2.2.7 Change usual place of residence', async () => { + await page + .locator('#deceased-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryDeceased').click() + await page.getByText(updatedDeceasedDetails.address.province).click() + + await page.locator('#districtPrimaryDeceased').click() + await page.getByText(updatedDeceasedDetails.address.district).click() + + await page + .locator('#cityPrimaryDeceased') + .fill(updatedDeceasedDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.number) + + await page + .locator('#postalCodePrimaryDeceased') + .fill(updatedDeceasedDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Sulaka', { ignoreCase: true }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Zobwe', { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.deceased.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.deceased.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.deceased.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.deceased.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.deceased.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#deceased-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.zipCode) + ).toBeVisible() + }) + + test('10.2.2.8 Change marital status', async () => { + await page + .locator('#deceased-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedDeceasedDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Marital').getByRole('deletion') + ).toHaveText('-') + + await expect( + page + .locator('#deceased-content #Marital') + .getByText(updatedDeceasedDetails.maritalStatus) + ).toBeVisible() + }) + + test('10.2.2.9 Change number of depandants', async () => { + await page + .getByRole('row', { name: 'No. of dependants' }) + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's number of depandants + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#numberOfDependants')).toBeTruthy() + + await page + .locator('#numberOfDependants') + .fill(updatedDeceasedDetails.NOdependants) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show new number of depandants + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .getByRole('row', { name: 'No. of dependants' }) + .getByText(updatedDeceasedDetails.NOdependants) + ).toBeVisible() + }) + }) + + test('10.2.3 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Continue' }) + ).toBeDisabled() + + await page.getByText('Select...').click() + await page.getByText('Affidavit', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Court Document', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Other', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('10.2.4 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Continue' }) + ).toBeDisabled() + + await page + .getByLabel('Myself or an agent made a mistake (Clerical error)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('10.2.5 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Send for approval button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('summary')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Send for approval' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Deceased)' + + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Deceased)' + + declaration.deceased.gender + + updatedDeceasedDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Deceased)' + + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Deceased)Farajaland' + + updatedDeceasedDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Deceased)National ID' + updatedDeceasedDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Deceased)-' + updatedDeceasedDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Deceased)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedDeceasedDetails.address.province + + updatedDeceasedDetails.address.district + + updatedDeceasedDetails.address.town + + updatedDeceasedDetails.address.residentialArea + + updatedDeceasedDetails.address.street + + updatedDeceasedDetails.address.number + + updatedDeceasedDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Deceased)-' + updatedDeceasedDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'No. of dependants (Deceased)-' + updatedDeceasedDetails.NOdependants + ) + ).toBeVisible() + + await expect( + page.getByText( + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + ) + ).toBeVisible() + await expect(page.getByText('Verified')).toBeVisible() + await expect( + page.getByText('Myself or an agent made a mistake (Clerical error)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('Yes').check() + await page + .locator('#correctionFees\\.nestedFields\\.totalFees') + .fill('15') + + await uploadImage(page, page.locator('#upload_document')) + + /* + * Expected result: should enable the Send for approval button + */ + await page.getByRole('button', { name: 'Send for approval' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should + * - be navigated to sent for approval tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/approvals')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + + test.describe('10.2.6 Correction Approval', async () => { + test.beforeAll(async ({ browser }) => { + await page.close() + page = await browser.newPage() + + await login(page, 'k.mweene', 'test') + await createPIN(page) + }) + + test('10.2.6.1 Record audit by local registrar', async () => { + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + await page.locator('#name_0').click() + }) + + test('10.2.6.2 Correction review', async () => { + await page.getByRole('button', { name: 'Review', exact: true }).click() + + /* + * Expected result: should show + * - Submitter + * - Requested by + * - Reason for request + * - Comments + * - Original vs correction + */ + + await expect( + page.getByText('Submitter' + 'Felix Katongo') + ).toBeVisible() + + await expect( + page.getByText( + 'Requested by' + + declaration.spouse.name[0].firstNames + + ' ' + + declaration.spouse.name[0].familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Reason for request' + + 'Myself or an agent made a mistake (Clerical error)' + ) + ).toBeVisible() + await expect( + page.getByText( + 'Comments' + declaration.registration.registrationNumber + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (Deceased)' + + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Deceased)' + + declaration.deceased.gender + + updatedDeceasedDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Deceased)' + + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Deceased)Farajaland' + + updatedDeceasedDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Deceased)National ID' + updatedDeceasedDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Deceased)-' + updatedDeceasedDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Deceased)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedDeceasedDetails.address.province + + updatedDeceasedDetails.address.district + + updatedDeceasedDetails.address.town + + updatedDeceasedDetails.address.residentialArea + + updatedDeceasedDetails.address.street + + updatedDeceasedDetails.address.number + + updatedDeceasedDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Deceased)-' + updatedDeceasedDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'No. of dependants (Deceased)-' + + updatedDeceasedDetails.NOdependants + ) + ).toBeVisible() + }) + + test('10.2.6.3 Approve correction', async () => { + await page.getByRole('button', { name: 'Approve', exact: true }).click() + await page.getByRole('button', { name: 'Confirm', exact: true }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the updated declaration in this tab + */ + expect(page.url().includes('registration-home/print')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText( + '1', + { + timeout: 1000 * 30 + } + ) + await expect( + page.getByText( + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + }) + test('10.2.6.4 Validate history in record audit', async () => { + await page + .getByText( + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + .click() + + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Correction requested + * - Correction approved + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction requested' }) + ).toBeVisible() + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction approved' }) + ).toBeVisible() + }) + }) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-11.spec.ts b/e2e/testcases/applications/correction/correct-record-11.spec.ts new file mode 100644 index 000000000..1a9cd633f --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-11.spec.ts @@ -0,0 +1,616 @@ +import { expect, test, type Page } from '@playwright/test' +import { + createPIN, + getLocationNameFromFhirId, + getToken, + login +} from '../../../helpers' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 11', () => { + let declaration: DeathDeclaration + let trackingId = '' + let deathLocation = '' + + let page: Page + + const updatedEventDetails = { + dateOfDeath: format( + subDays(new Date(), Math.ceil(20 * Math.random())), + 'yyyy-MM-dd' + ), + manner: 'Natural causes', + cause: { + established: true, + source: 'Physician' + }, + placeOfDeath: 'Estate Urban Health Centre' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('11.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('f.katongo', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + + deathLocation = + (await getLocationNameFromFhirId(declaration.eventLocation.id)) || + 'Not found' + }) + + test('11.1 Certificate preview', async () => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'No, make correction' }).click() + }) + + test('11.2 Correction requester: another registration agent or field agent', async () => { + await page.getByLabel('Another registration agent or field agent').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('11.3 Verify identity', async () => { + /* + * Expected result: + * - should not show verify identity + * - should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('11.4 Correction made on event details', async () => { + test('11.4.1 Change date of death', async () => { + await page + .locator('#deathEvent-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to death event details page + * - focus on date of death + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#deathDate')).toBeTruthy() + + const date = updatedEventDetails.dateOfDeath.split('-') + + await page.getByPlaceholder('dd').fill(date[2]) + await page.getByPlaceholder('mm').fill(date[1]) + await page.getByPlaceholder('yyyy').fill(date[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous date of death with strikethrough + * - show updated date of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Date').getByRole('deletion') + ).toHaveText( + format( + parseISO(declaration.deceased.deceased.deathDate), + 'dd MMMM yyyy' + ), + { ignoreCase: true } + ) + + await expect( + page + .locator('#deathEvent-content #Date') + .getByText( + format(parseISO(updatedEventDetails.dateOfDeath), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('11.4.2 Change manner of death', async () => { + await page + .locator('#deathEvent-content #Manner') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deathEvent details page + * - focus on manner of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#mannerOfDeath')).toBeTruthy() + + await page.locator('#mannerOfDeath').click() + await page.getByText(updatedEventDetails.manner, { exact: true }).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous manner with strikethrough + * - show updated manner + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Manner').getByRole('deletion') + ).toHaveText('-', { + ignoreCase: true + }) + + await expect( + page + .locator('#deathEvent-content #Manner') + .getByText(updatedEventDetails.manner) + ).toBeVisible() + }) + + test('11.4.3 Change cause of death, source', async () => { + await page + .locator('#deathEvent-content #Cause') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deathEvent details page + * - focus on cause of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#causeOfDeathEstablished')).toBeTruthy() + + await page.getByLabel('Cause of death has been established').check() + + await page.locator('#causeOfDeathMethod').click() + await page + .getByText(updatedEventDetails.cause.source, { exact: true }) + .click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous cause with strikethrough + * - show previous source of cause with strikethrough + * - show updated cause + * - show updated source of cause + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Cause').getByRole('deletion') + ).toHaveText( + declaration.causeOfDeathEstablished == 'true' ? 'Yes' : 'No', + { + ignoreCase: true + } + ) + + await expect( + page + .locator('#deathEvent-content #Cause') + .getByText(updatedEventDetails.cause.established ? 'Yes' : 'No') + ).toBeVisible() + + await expect( + page.locator('#deathEvent-content #Source').getByRole('deletion') + ).toHaveText('-', { + ignoreCase: true + }) + + await expect( + page + .locator('#deathEvent-content #Source') + .getByText(updatedEventDetails.cause.source) + ).toBeVisible() + }) + + test('11.4.4 Change place of death', async () => { + await page + .locator('#deathEvent-content #Place') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deathEvent details page + * - focus on place of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#placeOfDeath')).toBeTruthy() + + await page + .locator('#deathLocation') + .fill(updatedEventDetails.placeOfDeath.slice(0, 3)) + await page + .getByText(updatedEventDetails.placeOfDeath, { exact: true }) + .click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous place with strikethrough + * - show updated place + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Place').getByRole('deletion').nth(1) + ).toHaveText(deathLocation, { + ignoreCase: true + }) + + await expect( + page + .locator('#deathEvent-content #Place') + .getByText('Health Institution' + updatedEventDetails.placeOfDeath) + ).toBeVisible() + }) + }) + + test('11.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'I attest to seeing supporting documentation and have a copy filed at my office' + ) + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('11.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Informant provided incorrect information (Material error)') + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('11.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Send for approval button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Send for approval' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Date of death (Death event details)' + + format( + parseISO(declaration.deceased.deceased.deathDate), + 'dd MMMM yyyy' + ) + + format(parseISO(updatedEventDetails.dateOfDeath), 'dd MMMM yyyy') + ) + ).toBeVisible() + await expect( + page.getByText( + 'Manner of death (Death event details)-' + updatedEventDetails.manner + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Cause of death has been established (Death event details)' + + (declaration.causeOfDeathEstablished == 'true' ? 'Yes' : 'No') + + (updatedEventDetails.cause.established ? 'Yes' : 'No') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Source of cause of death (Death event details)-' + + updatedEventDetails.cause.source + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Place of death (Death event details)' + + 'Health Institution' + + deathLocation + + 'Health Institution' + + updatedEventDetails.placeOfDeath + ) + ).toBeVisible() + + await expect( + page.getByText('Another registration agent or field agent') + ).toBeVisible() + + await expect( + page.getByText( + 'Informant provided incorrect information (Material error)' + ) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Send for approval button + */ + await page.getByRole('button', { name: 'Send for approval' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should + * - be navigated to sent for approval tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/approvals')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + test.describe('11.8 Correction Approval', async () => { + test.beforeAll(async ({ browser }) => { + await page.close() + + page = await browser.newPage() + + await login(page, 'k.mweene', 'test') + await createPIN(page) + }) + + test('11.8.1 Record audit by local registrar', async () => { + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + await page.locator('#name_0').click() + }) + + test('11.8.2 Correction review', async () => { + await page.getByRole('button', { name: 'Review', exact: true }).click() + + /* + * Expected result: should show + * - Submitter + * - Requested by + * - Reason for request + * - Comments + * - Original vs correction + */ + + await expect(page.getByText('Submitter' + 'Felix Katongo')).toBeVisible() + + await expect( + page.getByText( + 'Requested by' + 'Another registration agent or field agent' + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Reason for request' + + 'Informant provided incorrect information (Material error)' + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of death (Death event details)' + + format( + parseISO(declaration.deceased.deceased.deathDate), + 'dd MMMM yyyy' + ) + + format(parseISO(updatedEventDetails.dateOfDeath), 'dd MMMM yyyy') + ) + ).toBeVisible() + await expect( + page.getByText( + 'Manner of death (Death event details)-' + updatedEventDetails.manner + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Cause of death has been established (Death event details)' + + (declaration.causeOfDeathEstablished == 'true' ? 'Yes' : 'No') + + (updatedEventDetails.cause.established ? 'Yes' : 'No') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Source of cause of death (Death event details)-' + + updatedEventDetails.cause.source + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Place of death (Death event details)' + + 'Health Institution' + + deathLocation + + 'Health Institution' + + updatedEventDetails.placeOfDeath + ) + ).toBeVisible() + + await expect( + page.getByText('Another registration agent or field agent') + ).toBeVisible() + }) + + test('11.8.3 Reject correction', async () => { + await page.getByRole('button', { name: 'Reject', exact: true }).click() + await page + .locator('#rejectionRaisonOfCorrection') + .fill('Wrong information') + await page.getByRole('button', { name: 'Confirm', exact: true }).click() + + await page.waitForTimeout(500) + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the updated declaration in this tab + */ + expect(page.url().includes('registration-home/print')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + + test('11.8.4 Validate history in record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Correction requested + * - Correction rejected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction requested' }) + ).toBeVisible() + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction rejected' }) + ).toBeVisible() + }) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-12.spec.ts b/e2e/testcases/applications/correction/correct-record-12.spec.ts new file mode 100644 index 000000000..f006678e5 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-12.spec.ts @@ -0,0 +1,950 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 12', () => { + let declaration: DeathDeclaration + let trackingId = '' + + let page: Page + + const updatedInformantDetails = { + type: 'Son', + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + sameAsDeceased: false, + country: 'Farajaland', + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('12.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('f.katongo', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test.describe('12.1 Print > Ready to issue', async () => { + test('12.1.1 Print', async () => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'Yes, print certificate' }).click() + await page.getByRole('button', { name: 'Print', exact: true }).click() + }) + + test('12.1.2 Ready to issue', async () => { + await page.getByRole('button', { name: 'Ready to issue' }).click() + + /* + * Expected result: should + * - be navigated to ready to isssue tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/readyToIssue')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + + test('12.1.3 Record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show correct record button + */ + await expect( + page.getByRole('button', { name: 'Correct record', exact: true }) + ).toBeVisible() + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + }) + + test('12.2 Correction requester: Me', async () => { + await page.getByLabel('Me', { exact: true }).check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('12.3 Verify identity', async () => { + /* + * Expected result: should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('12.4 Correction made on informant details', async () => { + test('12.4.1 Change informant type', async () => { + await page + .locator('#informant-content #Informant') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantType')).toBeTruthy() + + await page.locator('#informantType').click() + await page + .getByText(updatedInformantDetails.type, { exact: true }) + .click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous type with strikethrough + * - show updated type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Informant').getByRole('deletion') + ).toHaveText(declaration.registration.informantType, { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Informant') + .getByText(updatedInformantDetails.type) + ).toBeVisible() + }) + + test('12.4.2 Change name', async () => { + await page + .locator('#informant-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + // expect(page.url().includes('#familyNameEng')).toBeTruthy() => this fails + + await page + .locator('#firstNamesEng') + .fill(updatedInformantDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedInformantDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#informant-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.informant.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.informant.name[0].familyName + ) + + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.familyName) + ).toBeVisible() + }) + + test('12.4.3 Change date of birth', async () => { + await page + .locator('#informant-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantBirthDate')).toBeTruthy() + + const birthDay = updatedInformantDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#informant-content #Date') + .getByText( + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('12.4.4 Change nationality', async () => { + await page + .locator('#informant-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedInformantDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Nationality') + .getByText(updatedInformantDetails.nationality) + ).toBeVisible() + }) + + test('12.4.5 Change id type', async () => { + await page + .locator('#informant-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantIdType')).toBeTruthy() + + await page.locator('#informantIdType').click() + await page.getByText(updatedInformantDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Type').getByRole('deletion') + ).toHaveText('-') + + await expect( + page + .locator('#informant-content #Type') + .getByText(updatedInformantDetails.idType) + ).toBeVisible() + }) + + test('12.4.6 Change id', async () => { + await page + .locator('#informant-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantPassport')).toBeTruthy() + + await page.locator('#informantPassport').fill(updatedInformantDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#informant-content #ID') + .getByText(updatedInformantDetails.id) + ).toBeVisible() + }) + + test('12.4.7 Change usual place of residence', async () => { + await page + .locator('#informant-content #Same') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect( + page.url().includes('#primaryAddressSameAsOtherPrimary') + ).toBeTruthy() + + await page.getByLabel('No', { exact: true }).check() + + await page.locator('#statePrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.province).click() + + await page.locator('#districtPrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.district).click() + + await page + .locator('#cityPrimaryInformant') + .fill(updatedInformantDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.number) + + await page + .locator('#postalCodePrimaryInformant') + .fill(updatedInformantDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.zipCode) + ).toBeVisible() + }) + + test('12.4.8 Change email', async () => { + await page + .locator('#informant-content #Email') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on registration email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#registrationEmail')).toBeTruthy() + + await page + .locator('#registrationEmail') + .fill(updatedInformantDetails.email) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous email with strikethrough + * - show updated email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Email').getByRole('deletion') + ).toHaveText(declaration.registration.contactEmail, { + ignoreCase: true + }) + await expect( + page + .locator('#informant-content #Email') + .getByText(updatedInformantDetails.email) + ).toBeVisible() + }) + }) + + test('12.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('No supporting documents required').check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('12.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'Informant did not provide this information (Material omission)' + ) + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('12.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Send for approval button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Send for approval' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Informant type (Informant)' + + declaration.registration.informantType + + updatedInformantDetails.type + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText('Type of ID (Informant)-' + updatedInformantDetails.idType) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + "Same as deceased's usual place of residence? (Informant)" + + 'Yes' + + 'No' + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + + await expect(page.getByText('Me', { exact: true })).toBeVisible() + await expect( + page.getByText( + 'Informant did not provide this information (Material omission)' + ) + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Send for approval button + */ + await page.getByRole('button', { name: 'Send for approval' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should + * - be navigated to sent for approval tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/approvals')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + + test.describe('12.8 Correction Approval', async () => { + test.beforeAll(async ({ browser }) => { + await page.close() + + page = await browser.newPage() + + await login(page, 'k.mweene', 'test') + await createPIN(page) + }) + + test('12.8.1 Record audit by local registrar', async () => { + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + await page.locator('#name_0').click() + }) + + test('12.8.2 Correction review', async () => { + await page.getByRole('button', { name: 'Review', exact: true }).click() + + /* + * Expected result: should show + * - Submitter + * - Requested by + * - Reason for request + * - Comments + * - Original vs correction + */ + + await expect(page.getByText('Submitter' + 'Felix Katongo')).toBeVisible() + + await expect(page.getByText('Requested by' + 'Me')).toBeVisible() + await expect( + page.getByText( + 'Reason for request' + + 'Informant did not provide this information (Material omission)' + ) + ).toBeVisible() + + await expect( + page.getByText('Comments' + declaration.registration.registrationNumber) + ).toBeVisible() + + await expect( + page.getByText( + 'Informant type (Informant)' + + declaration.registration.informantType + + updatedInformantDetails.type + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Informant)-' + updatedInformantDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + "Same as deceased's usual place of residence? (Informant)" + + 'Yes' + + 'No' + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + }) + + test('12.8.3 Approve correction', async () => { + await page.getByRole('button', { name: 'Approve', exact: true }).click() + await page.getByRole('button', { name: 'Confirm', exact: true }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the updated declaration in this tab + */ + expect(page.url().includes('registration-home/print')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + + test('12.8.4 Validate history in record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Correction requested + * - Correction approved + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction requested' }) + ).toBeVisible() + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction approved' }) + ).toBeVisible() + }) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-13.spec.ts b/e2e/testcases/applications/correction/correct-record-13.spec.ts new file mode 100644 index 000000000..3fa678e41 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-13.spec.ts @@ -0,0 +1,700 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login, uploadImage } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 13', () => { + let declaration: DeathDeclaration + let trackingId = '' + + let page: Page + + const updatedSpouseDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + sameAsDeceased: false, + province: 'Pualula', + district: 'Ienge', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('13.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('k.mweene', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test('13.1 Ready to print > record audit', async () => { + await login(page, 'k.mweene', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + + test('13.2 Correction requester: Someone Else (Cousin)', async () => { + await page.getByLabel('Someone Else').check() + await page.getByPlaceholder('Eg. Grandmother').fill('Cousin') + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('13.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * nothing + */ + + await page.getByRole('button', { name: 'Verified' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('13.4 Correction made on spouse details', async () => { + test('13.4.1 Change name', async () => { + await page + .locator('#spouse-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedSpouseDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedSpouseDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#spouse-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.spouse.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.spouse.name[0].familyName) + + await expect( + page + .locator('#spouse-content #Full') + .getByText(updatedSpouseDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Full') + .getByText(updatedSpouseDetails.familyName) + ).toBeVisible() + }) + + test('13.4.2 Change date of birth', async () => { + await page + .locator('#spouse-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#spouseBirthDate')).toBeTruthy() + + const birthDay = updatedSpouseDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.spouse.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#spouse-content #Date') + .getByText( + format(parseISO(updatedSpouseDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('13.4.3 Change nationality', async () => { + await page + .locator('#spouse-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedSpouseDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#spouse-content #Nationality') + .getByText(updatedSpouseDetails.nationality) + ).toBeVisible() + }) + + test('13.4.4 Change id type', async () => { + await page + .locator('#spouse-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#spouseIdType')).toBeTruthy() + + await page.locator('#spouseIdType').click() + await page.getByText(updatedSpouseDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#spouse-content #Type') + .getByText(updatedSpouseDetails.idType) + ).toBeVisible() + }) + + test('13.4.5 Change id', async () => { + await page + .locator('#spouse-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#spousePassport')).toBeTruthy() + + await page.locator('#spousePassport').fill(updatedSpouseDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #ID').getByText(updatedSpouseDetails.id) + ).toBeVisible() + }) + + test('13.4.6 Change usual place of residence', async () => { + await page + .locator('#spouse-content #Same') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect( + page.url().includes('#primaryAddressSameAsOtherPrimary') + ).toBeTruthy() + + await page.getByLabel('No', { exact: true }).check() + + await page.locator('#statePrimarySpouse').click() + await page.getByText(updatedSpouseDetails.address.province).click() + + await page.locator('#districtPrimarySpouse').click() + await page.getByText(updatedSpouseDetails.address.district).click() + + await page + .locator('#cityPrimarySpouse') + .fill(updatedSpouseDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimarySpouse') + .fill(updatedSpouseDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimarySpouse') + .fill(updatedSpouseDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimarySpouse') + .fill(updatedSpouseDetails.address.number) + + await page + .locator('#postalCodePrimarySpouse') + .fill(updatedSpouseDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Sulaka', { ignoreCase: true }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Zobwe', { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.spouse.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.spouse.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.spouse.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.spouse.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.spouse.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#spouse-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.zipCode) + ).toBeVisible() + }) + }) + + test('13.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByText('Select...').click() + await page.getByText('Affidavit', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Court Document', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Other', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('13.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Requested to do so by the court (Judicial order)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('13.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Spouse details)' + + declaration.spouse.name[0].firstNames + + ' ' + + declaration.spouse.name[0].familyName + + updatedSpouseDetails.firstNames + + ' ' + + updatedSpouseDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Spouse details)' + + format(parseISO(declaration.spouse.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedSpouseDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Spouse details)Farajaland' + + updatedSpouseDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Spouse details)National ID' + updatedSpouseDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Spouse details)-' + updatedSpouseDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Spouse details)FarajalandSulakaZobwe-' + + declaration.spouse.address[0].city + + declaration.spouse.address[0].line[2] + + declaration.spouse.address[0].line[1] + + declaration.spouse.address[0].line[0] + + declaration.spouse.address[0].postalCode + + 'Farajaland' + + updatedSpouseDetails.address.province + + updatedSpouseDetails.address.district + + updatedSpouseDetails.address.town + + updatedSpouseDetails.address.residentialArea + + updatedSpouseDetails.address.street + + updatedSpouseDetails.address.number + + updatedSpouseDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + "Same as deceased's usual place of residence? (Spouse details)" + + 'Yes' + + 'No' + ) + ).toBeVisible() + + await expect(page.getByText('Cousin')).toBeVisible() + await expect(page.getByText('Verified')).toBeVisible() + await expect( + page.getByText('Requested to do so by the court (Judicial order)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('Yes').check() + await page.locator('#correctionFees\\.nestedFields\\.totalFees').fill('15') + + await uploadImage(page, page.locator('#upload_document')) + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + + /* + * Expected result: should open modal saying + * Correct record ? + * The informant will be notified of this correction and a record of this decision will be recorded + * Cancel button + * Confirm button + */ + + await expect(page.getByText('Correct record ?')).toBeVisible() + await expect( + page.getByText( + 'The informant will be notified of this correction and a record of this decision will be recorded' + ) + ).toBeVisible() + + await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Confirm' })).toBeVisible() + + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + test('13.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-14.spec.ts b/e2e/testcases/applications/correction/correct-record-14.spec.ts new file mode 100644 index 000000000..0c22036d3 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-14.spec.ts @@ -0,0 +1,825 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 14', () => { + let declaration: DeathDeclaration + let trackingId = '' + + let page: Page + const updatedDeceasedDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + gender: 'Female', + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random()) + 365 * 25), + 'yyyy-MM-dd' + ), + nationality: 'Canada', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Pualula', + district: 'Pili', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + NOdependants: '3', + reason: 'Change of mind' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('14.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('k.mweene', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test('14.1 Certificate preview', async () => { + await login(page, 'k.mweene', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'No, make correction' }).click() + }) + + test('14.2 Correction requester: Court', async () => { + await page.getByLabel('Court').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('14.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * nothing + */ + + await page.getByRole('button', { name: 'Identity does not match' }).click() + + /* + * Expected result: should show modal with + * - Correct without proof of ID? + * - Please be aware that if you proceed, you will be responsible + * for making a change to this record without the necessary proof of identification + * - Confirm button + * - Cancel button + */ + await expect(page.getByText('Correct without proof of ID?')).toBeVisible() + await expect( + page.getByText( + 'Please be aware that if you proceed, you will be responsible for making a change to this record without the necessary proof of identification' + ) + ).toBeVisible() + await expect(page.getByRole('button', { name: 'Confirm' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('14.4.2 Correction made on child details', async () => { + test('10.2.2.1 Change name', async () => { + await page + .locator('#deceased-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page + .locator('#firstNamesEng') + .fill(updatedDeceasedDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedDeceasedDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#deceased-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.deceased.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.deceased.name[0].familyName + ) + + await expect( + page + .locator('#deceased-content #Full') + .getByText(updatedDeceasedDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Full') + .getByText(updatedDeceasedDetails.familyName) + ).toBeVisible() + }) + + test('10.2.2.2 Change gender', async () => { + await page + .locator('#deceased-content #Sex') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#gender')).toBeTruthy() + + await page.locator('#gender').click() + await page.getByText(updatedDeceasedDetails.gender).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Sex').getByRole('deletion') + ).toHaveText(declaration.deceased.gender, { ignoreCase: true }) + + await expect( + page + .locator('#deceased-content #Sex') + .getByText(updatedDeceasedDetails.gender) + ).toBeVisible() + }) + + test('10.2.2.3 Change date of birth', async () => { + await page + .locator('#deceased-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedBirthDate')).toBeTruthy() + + const birthDay = updatedDeceasedDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#deceased-content #Date') + .getByText( + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('10.2.2.4 Change nationality', async () => { + await page + .locator('#deceased-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedDeceasedDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#deceased-content #Nationality') + .getByText(updatedDeceasedDetails.nationality) + ).toBeVisible() + }) + + test('10.2.2.5 Change id type', async () => { + await page + .locator('#deceased-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedIdType')).toBeTruthy() + + await page.locator('#deceasedIdType').click() + await page.getByText(updatedDeceasedDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#deceased-content #Type') + .getByText(updatedDeceasedDetails.idType) + ).toBeVisible() + }) + + test('10.2.2.6 Change id', async () => { + await page + .locator('#deceased-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedPassport')).toBeTruthy() + + await page.locator('#deceasedPassport').fill(updatedDeceasedDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#deceased-content #ID') + .getByText(updatedDeceasedDetails.id) + ).toBeVisible() + }) + + test('10.2.2.7 Change usual place of residence', async () => { + await page + .locator('#deceased-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryDeceased').click() + await page.getByText(updatedDeceasedDetails.address.province).click() + + await page.locator('#districtPrimaryDeceased').click() + await page.getByText(updatedDeceasedDetails.address.district).click() + + await page + .locator('#cityPrimaryDeceased') + .fill(updatedDeceasedDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.number) + + await page + .locator('#postalCodePrimaryDeceased') + .fill(updatedDeceasedDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Sulaka', { ignoreCase: true }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Zobwe', { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.deceased.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.deceased.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.deceased.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.deceased.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.deceased.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#deceased-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.zipCode) + ).toBeVisible() + }) + + test('10.2.2.8 Change marital status', async () => { + await page + .locator('#deceased-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedDeceasedDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Marital').getByRole('deletion') + ).toHaveText('-') + + await expect( + page + .locator('#deceased-content #Marital') + .getByText(updatedDeceasedDetails.maritalStatus) + ).toBeVisible() + }) + + test('10.2.2.9 Change number of depandants', async () => { + await page + .getByRole('row', { name: 'No. of dependants' }) + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's number of depandants + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#numberOfDependants')).toBeTruthy() + + await page + .locator('#numberOfDependants') + .fill(updatedDeceasedDetails.NOdependants) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show new number of depandants + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .getByRole('row', { name: 'No. of dependants' }) + .getByText(updatedDeceasedDetails.NOdependants) + ).toBeVisible() + }) + }) + + test('14.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'I attest to seeing supporting documentation and have a copy filed at my office' + ) + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('14.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('Other').check() + await page + .locator('#type\\.nestedFields\\.otherReason') + .fill(updatedDeceasedDetails.reason) + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('14.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Deceased)' + + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Deceased)' + + declaration.deceased.gender + + updatedDeceasedDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Deceased)' + + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Deceased)Farajaland' + updatedDeceasedDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Deceased)National ID' + updatedDeceasedDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Deceased)-' + updatedDeceasedDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Deceased)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedDeceasedDetails.address.province + + updatedDeceasedDetails.address.district + + updatedDeceasedDetails.address.town + + updatedDeceasedDetails.address.residentialArea + + updatedDeceasedDetails.address.street + + updatedDeceasedDetails.address.number + + updatedDeceasedDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Deceased)-' + updatedDeceasedDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'No. of dependants (Deceased)-' + updatedDeceasedDetails.NOdependants + ) + ).toBeVisible() + await expect(page.getByText('Court')).toBeVisible() + await expect(page.getByText(updatedDeceasedDetails.reason)).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + }) + test('14.8 Validate history in record audit', async () => { + await page + .getByText( + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + .click() + + await page.getByLabel('Assign record').click() + + if (await page.getByText('Unassign record?', { exact: true }).isVisible()) + await page.getByRole('button', { name: 'Cancel', exact: true }).click() + else if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-15.spec.ts b/e2e/testcases/applications/correction/correct-record-15.spec.ts new file mode 100644 index 000000000..a28556f00 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-15.spec.ts @@ -0,0 +1,578 @@ +import { expect, test, type Page } from '@playwright/test' +import { + createPIN, + getLocationNameFromFhirId, + getToken, + login +} from '../../../helpers' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 15', () => { + let declaration: DeathDeclaration + let trackingId = '' + let deathLocation = '' + + let page: Page + const updatedEventDetails = { + dateOfDeath: format( + subDays(new Date(), Math.ceil(20 * Math.random())), + 'yyyy-MM-dd' + ), + manner: 'Natural causes', + cause: { + established: true, + source: 'Physician' + }, + placeOfDeath: 'Estate Urban Health Centre' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('15.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('k.mweene', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + + deathLocation = + (await getLocationNameFromFhirId(declaration.eventLocation.id)) || + 'Not found' + }) + + test.describe('15.1 Print > Ready to issue', async () => { + test('15.1.1 print', async () => { + await login(page, 'k.mweene', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'Yes, print certificate' }).click() + await page.getByRole('button', { name: 'Print', exact: true }).click() + }) + test('15.1.2 Ready to issue', async () => { + await page.getByRole('button', { name: 'Ready to issue' }).click() + + /* + * Expected result: should + * - be navigated to ready to isssue tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/readyToIssue')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + }) + test('15.1.3 Record audit', async () => { + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show correct record button + */ + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + }) + + test('15.2 Correction requester: Informant (SPOUSE)', async () => { + await page.getByLabel('Informant (SPOUSE)').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('15.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * ID + * First Name + * Last Name + * Date of Birth + * Nationality + */ + await expect( + page.getByText( + `ID: National Id | ${declaration.informant.identifier[0].id}` + ) + ).toBeVisible() + await expect( + page.getByText( + `First name(s): ${declaration.informant.name[0].firstNames}` + ) + ).toBeVisible() + await expect( + page.getByText(`Last name: ${declaration.informant.name[0].familyName}`) + ).toBeVisible() + await expect( + page.getByText( + `Date of Birth: + ${format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy')} + ` + ) + ).toBeVisible() + await expect( + page.getByText(`Nationality: ${declaration.informant.nationality}`) + ).toBeVisible() + + await page.getByRole('button', { name: 'Identity does not match' }).click() + + /* + * Expected result: should show modal with + * - Correct without proof of ID? + * - Please be aware that if you proceed, you will be responsible + * for making a change to this record without the necessary proof of identification + * - Confirm button + * - Cancel button + */ + await expect(page.getByText('Correct without proof of ID?')).toBeVisible() + await expect( + page.getByText( + 'Please be aware that if you proceed, you will be responsible for making a change to this record without the necessary proof of identification' + ) + ).toBeVisible() + await expect(page.getByRole('button', { name: 'Confirm' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should navigate to review page + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('15.4 Correction made on event details', async () => { + test('15.4.1 Change date of death', async () => { + await page + .locator('#deathEvent-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to death event details page + * - focus on date of death + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#deathDate')).toBeTruthy() + + const date = updatedEventDetails.dateOfDeath.split('-') + + await page.getByPlaceholder('dd').fill(date[2]) + await page.getByPlaceholder('mm').fill(date[1]) + await page.getByPlaceholder('yyyy').fill(date[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous date of death with strikethrough + * - show updated date of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Date').getByRole('deletion') + ).toHaveText( + format( + parseISO(declaration.deceased.deceased.deathDate), + 'dd MMMM yyyy' + ), + { ignoreCase: true } + ) + + await expect( + page + .locator('#deathEvent-content #Date') + .getByText( + format(parseISO(updatedEventDetails.dateOfDeath), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('15.4.2 Change manner of death', async () => { + await page + .locator('#deathEvent-content #Manner') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deathEvent details page + * - focus on manner of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#mannerOfDeath')).toBeTruthy() + + await page.locator('#mannerOfDeath').click() + await page.getByText(updatedEventDetails.manner, { exact: true }).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous manner with strikethrough + * - show updated manner + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Manner').getByRole('deletion') + ).toHaveText('-', { + ignoreCase: true + }) + + await expect( + page + .locator('#deathEvent-content #Manner') + .getByText(updatedEventDetails.manner) + ).toBeVisible() + }) + + test('15.4.3 Change cause of death, source', async () => { + await page + .locator('#deathEvent-content #Cause') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deathEvent details page + * - focus on cause of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#causeOfDeathEstablished')).toBeTruthy() + + await page.getByLabel('Cause of death has been established').check() + + await page.locator('#causeOfDeathMethod').click() + await page + .getByText(updatedEventDetails.cause.source, { exact: true }) + .click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous cause with strikethrough + * - show previous source of cause with strikethrough + * - show updated cause + * - show updated source of cause + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Cause').getByRole('deletion') + ).toHaveText( + declaration.causeOfDeathEstablished == 'true' ? 'Yes' : 'No', + { + ignoreCase: true + } + ) + + await expect( + page + .locator('#deathEvent-content #Cause') + .getByText(updatedEventDetails.cause.established ? 'Yes' : 'No') + ).toBeVisible() + + await expect( + page.locator('#deathEvent-content #Source').getByRole('deletion') + ).toHaveText('-', { + ignoreCase: true + }) + + await expect( + page + .locator('#deathEvent-content #Source') + .getByText(updatedEventDetails.cause.source) + ).toBeVisible() + }) + + test('15.4.4 Change place of death', async () => { + await page + .locator('#deathEvent-content #Place') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deathEvent details page + * - focus on place of death + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('death-event-details')).toBeTruthy() + expect(page.url().includes('#placeOfDeath')).toBeTruthy() + + await page + .locator('#deathLocation') + .fill(updatedEventDetails.placeOfDeath.slice(0, 3)) + await page + .getByText(updatedEventDetails.placeOfDeath, { exact: true }) + .click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous place with strikethrough + * - show updated place + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deathEvent-content #Place').getByRole('deletion').nth(1) + ).toHaveText(deathLocation, { + ignoreCase: true + }) + + await expect( + page + .locator('#deathEvent-content #Place') + .getByText('Health Institution' + updatedEventDetails.placeOfDeath) + ).toBeVisible() + }) + }) + + test('15.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('No supporting documents required').check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('15.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Myself or an agent made a mistake (Clerical error)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('15.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Date of death (Death event details)' + + format( + parseISO(declaration.deceased.deceased.deathDate), + 'dd MMMM yyyy' + ) + + format(parseISO(updatedEventDetails.dateOfDeath), 'dd MMMM yyyy') + ) + ).toBeVisible() + await expect( + page.getByText( + 'Manner of death (Death event details)-' + updatedEventDetails.manner + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Cause of death has been established (Death event details)' + + (declaration.causeOfDeathEstablished == 'true' ? 'Yes' : 'No') + + (updatedEventDetails.cause.established ? 'Yes' : 'No') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Source of cause of death (Death event details)-' + + updatedEventDetails.cause.source + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Place of death (Death event details)' + + 'Health Institution' + + deathLocation + + 'Health Institution' + + updatedEventDetails.placeOfDeath + ) + ).toBeVisible() + + await expect( + page.getByText( + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + ) + ).toBeVisible() + + await expect(page.getByText('Identity does not match')).toBeVisible() + + await expect( + page.getByText('Myself or an agent made a mistake (Clerical error)') + ).toBeVisible() + + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + test('15.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-16.spec.ts b/e2e/testcases/applications/correction/correct-record-16.spec.ts new file mode 100644 index 000000000..cd793a782 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-16.spec.ts @@ -0,0 +1,762 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login, uploadImage } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 16', () => { + let declaration: DeathDeclaration + let trackingId = '' + + let page: Page + const updatedInformantDetails = { + type: 'Son', + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + sameAsDeceased: false, + country: 'Farajaland', + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('16.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('j.musonda', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test('16.1 Ready to print > record audit', async () => { + await login(page, 'j.musonda', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + + test('16.2 Correction requester: Another registration agent or field agent', async () => { + await page.getByLabel('Another registration agent or field agent').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('16.3 Verify identity', async () => { + /* + * Expected result: + * - should not show verify identity + * - should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('16.4 Correction made on informant details', async () => { + test('16.4.1 Change informant type', async () => { + await page + .locator('#informant-content #Informant') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantType')).toBeTruthy() + + await page.locator('#informantType').click() + await page + .getByText(updatedInformantDetails.type, { exact: true }) + .click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous type with strikethrough + * - show updated type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Informant').getByRole('deletion') + ).toHaveText(declaration.registration.informantType, { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Informant') + .getByText(updatedInformantDetails.type) + ).toBeVisible() + }) + + test('16.4.2 Change name', async () => { + await page + .locator('#informant-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + // expect(page.url().includes('#familyNameEng')).toBeTruthy() => this fails + + await page + .locator('#firstNamesEng') + .fill(updatedInformantDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedInformantDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#informant-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.informant.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.informant.name[0].familyName + ) + + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.familyName) + ).toBeVisible() + }) + + test('16.4.3 Change date of birth', async () => { + await page + .locator('#informant-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantBirthDate')).toBeTruthy() + + const birthDay = updatedInformantDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#informant-content #Date') + .getByText( + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('16.4.4 Change nationality', async () => { + await page + .locator('#informant-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedInformantDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Nationality') + .getByText(updatedInformantDetails.nationality) + ).toBeVisible() + }) + + test('16.4.5 Change id type', async () => { + await page + .locator('#informant-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantIdType')).toBeTruthy() + + await page.locator('#informantIdType').click() + await page.getByText(updatedInformantDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Type').getByRole('deletion') + ).toHaveText('-') + + await expect( + page + .locator('#informant-content #Type') + .getByText(updatedInformantDetails.idType) + ).toBeVisible() + }) + + test('16.4.6 Change id', async () => { + await page + .locator('#informant-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantPassport')).toBeTruthy() + + await page.locator('#informantPassport').fill(updatedInformantDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#informant-content #ID') + .getByText(updatedInformantDetails.id) + ).toBeVisible() + }) + + test('16.4.7 Change usual place of residence', async () => { + await page + .locator('#informant-content #Same') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect( + page.url().includes('#primaryAddressSameAsOtherPrimary') + ).toBeTruthy() + + await page.getByLabel('No', { exact: true }).check() + + await page.locator('#statePrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.province).click() + + await page.locator('#districtPrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.district).click() + + await page + .locator('#cityPrimaryInformant') + .fill(updatedInformantDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.number) + + await page + .locator('#postalCodePrimaryInformant') + .fill(updatedInformantDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.zipCode) + ).toBeVisible() + }) + + test('16.4.8 Change email', async () => { + await page + .locator('#informant-content #Email') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on registration email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#registrationEmail')).toBeTruthy() + + await page + .locator('#registrationEmail') + .fill(updatedInformantDetails.email) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous email with strikethrough + * - show updated email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Email').getByRole('deletion') + ).toHaveText(declaration.registration.contactEmail, { + ignoreCase: true + }) + await expect( + page + .locator('#informant-content #Email') + .getByText(updatedInformantDetails.email) + ).toBeVisible() + }) + }) + + test('16.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByText('Select...').click() + await page.getByText('Affidavit', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page + .getByText('Court Document', { + exact: true + }) + .click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Other', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('16.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Informant provided incorrect information (Material error)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('16.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Informant type (Informant)' + + declaration.registration.informantType + + updatedInformantDetails.type + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText('Type of ID (Informant)-' + updatedInformantDetails.idType) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + "Same as deceased's usual place of residence? (Informant)" + + 'Yes' + + 'No' + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + + await expect( + page.getByText('Another registration agent or field agent', { + exact: true + }) + ).toBeVisible() + await expect( + page.getByText( + 'Informant provided incorrect information (Material error)' + ) + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('Yes').check() + await page.locator('#correctionFees\\.nestedFields\\.totalFees').fill('15') + + await uploadImage(page, page.locator('#upload_document')) + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + test('16.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-17.spec.ts b/e2e/testcases/applications/correction/correct-record-17.spec.ts new file mode 100644 index 000000000..34ed6ba34 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-17.spec.ts @@ -0,0 +1,665 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 17', () => { + let declaration: DeathDeclaration + let trackingId = '' + + let page: Page + + const updatedSpouseDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + sameAsDeceased: false, + province: 'Pualula', + district: 'Ienge', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('17.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('j.musonda', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test('17.1 Certificate preview', async () => { + await login(page, 'j.musonda', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'No, make correction' }).click() + }) + + test('17.2 Correction requester: Me', async () => { + await page.getByLabel('Me', { exact: true }).check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('17.3 Verify identity', async () => { + /* + * Expected result: should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('17.4 Correction made on spouse details', async () => { + test('17.4.1 Change name', async () => { + await page + .locator('#spouse-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedSpouseDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedSpouseDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#spouse-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.spouse.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.spouse.name[0].familyName) + + await expect( + page + .locator('#spouse-content #Full') + .getByText(updatedSpouseDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Full') + .getByText(updatedSpouseDetails.familyName) + ).toBeVisible() + }) + + test('17.4.2 Change date of birth', async () => { + await page + .locator('#spouse-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#spouseBirthDate')).toBeTruthy() + + const birthDay = updatedSpouseDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.spouse.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#spouse-content #Date') + .getByText( + format(parseISO(updatedSpouseDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('17.4.3 Change nationality', async () => { + await page + .locator('#spouse-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedSpouseDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#spouse-content #Nationality') + .getByText(updatedSpouseDetails.nationality) + ).toBeVisible() + }) + + test('17.4.4 Change id type', async () => { + await page + .locator('#spouse-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#spouseIdType')).toBeTruthy() + + await page.locator('#spouseIdType').click() + await page.getByText(updatedSpouseDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#spouse-content #Type') + .getByText(updatedSpouseDetails.idType) + ).toBeVisible() + }) + + test('17.4.5 Change id', async () => { + await page + .locator('#spouse-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect(page.url().includes('#spousePassport')).toBeTruthy() + + await page.locator('#spousePassport').fill(updatedSpouseDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #ID').getByText(updatedSpouseDetails.id) + ).toBeVisible() + }) + + test('17.4.6 Change usual place of residence', async () => { + await page + .locator('#spouse-content #Same') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to spouse's details page + * - focus on spouse's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('spouse-view-group')).toBeTruthy() + expect( + page.url().includes('#primaryAddressSameAsOtherPrimary') + ).toBeTruthy() + + await page.getByLabel('No', { exact: true }).check() + + await page.locator('#statePrimarySpouse').click() + await page.getByText(updatedSpouseDetails.address.province).click() + + await page.locator('#districtPrimarySpouse').click() + await page.getByText(updatedSpouseDetails.address.district).click() + + await page + .locator('#cityPrimarySpouse') + .fill(updatedSpouseDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimarySpouse') + .fill(updatedSpouseDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimarySpouse') + .fill(updatedSpouseDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimarySpouse') + .fill(updatedSpouseDetails.address.number) + + await page + .locator('#postalCodePrimarySpouse') + .fill(updatedSpouseDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Sulaka', { ignoreCase: true }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Zobwe', { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.spouse.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.spouse.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.spouse.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.spouse.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#spouse-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.spouse.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#spouse-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#spouse-content #Usual') + .getByText(updatedSpouseDetails.address.zipCode) + ).toBeVisible() + }) + }) + + test('17.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'I attest to seeing supporting documentation and have a copy filed at my office' + ) + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('17.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'Informant did not provide this information (Material omission)' + ) + .check() + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('17.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Spouse details)' + + declaration.spouse.name[0].firstNames + + ' ' + + declaration.spouse.name[0].familyName + + updatedSpouseDetails.firstNames + + ' ' + + updatedSpouseDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Spouse details)' + + format(parseISO(declaration.spouse.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedSpouseDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Spouse details)Farajaland' + + updatedSpouseDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Spouse details)National ID' + updatedSpouseDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Spouse details)-' + updatedSpouseDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Spouse details)FarajalandSulakaZobwe-' + + declaration.spouse.address[0].city + + declaration.spouse.address[0].line[2] + + declaration.spouse.address[0].line[1] + + declaration.spouse.address[0].line[0] + + declaration.spouse.address[0].postalCode + + 'Farajaland' + + updatedSpouseDetails.address.province + + updatedSpouseDetails.address.district + + updatedSpouseDetails.address.town + + updatedSpouseDetails.address.residentialArea + + updatedSpouseDetails.address.street + + updatedSpouseDetails.address.number + + updatedSpouseDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + "Same as deceased's usual place of residence? (Spouse details)" + + 'Yes' + + 'No' + ) + ).toBeVisible() + + await expect(page.getByText('Me', { exact: true })).toBeVisible() + await expect( + page.getByText( + 'Informant did not provide this information (Material omission)' + ) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + }) + test('17.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + + if (await page.getByText('Unassign record?', { exact: true }).isVisible()) + await page.getByRole('button', { name: 'Cancel', exact: true }).click() + else if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-18.spec.ts b/e2e/testcases/applications/correction/correct-record-18.spec.ts new file mode 100644 index 000000000..3af43532b --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-18.spec.ts @@ -0,0 +1,871 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { format, parseISO, subDays } from 'date-fns' +import { DeathDeclaration } from '../../death/types' +import { createDeathDeclaration, fetchDeclaration } from '../../death/helpers' + +test.describe.serial(' Correct record - 18', () => { + let declaration: DeathDeclaration + let trackingId = '' + + let page: Page + const updatedDeceasedDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + gender: 'Female', + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random()) + 365 * 25), + 'yyyy-MM-dd' + ), + nationality: 'Canada', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Pualula', + district: 'Pili', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + NOdependants: '3' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('18.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + + const res = await createDeathDeclaration(token) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('j.musonda', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchDeathRegistration as DeathDeclaration + }) + + test.describe('18.1 Print > Ready to issue', async () => { + test('18.1.1 print', async () => { + await login(page, 'j.musonda', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'Yes, print certificate' }).click() + await page.getByRole('button', { name: 'Print', exact: true }).click() + }) + test('18.1.2 Ready to issue', async () => { + await page.getByRole('button', { name: 'Ready to issue' }).click() + + /* + * Expected result: should + * - be navigated to ready to isssue tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/readyToIssue')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + ).toBeVisible() + + await page + .getByText( + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + ) + .click() + }) + test('18.1.3 Record audit', async () => { + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show correct record button + */ + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + }) + + test('14.2 Correction requester: Court', async () => { + await page.getByLabel('Court').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('14.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * nothing + */ + + await page.getByRole('button', { name: 'Identity does not match' }).click() + + /* + * Expected result: should show modal with + * - Correct without proof of ID? + * - Please be aware that if you proceed, you will be responsible + * for making a change to this record without the necessary proof of identification + * - Confirm button + * - Cancel button + */ + await expect(page.getByText('Correct without proof of ID?')).toBeVisible() + await expect( + page.getByText( + 'Please be aware that if you proceed, you will be responsible for making a change to this record without the necessary proof of identification' + ) + ).toBeVisible() + await expect(page.getByRole('button', { name: 'Confirm' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('14.4.2 Correction made on child details', async () => { + test('10.2.2.1 Change name', async () => { + await page + .locator('#deceased-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page + .locator('#firstNamesEng') + .fill(updatedDeceasedDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedDeceasedDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#deceased-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.deceased.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.deceased.name[0].familyName + ) + + await expect( + page + .locator('#deceased-content #Full') + .getByText(updatedDeceasedDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Full') + .getByText(updatedDeceasedDetails.familyName) + ).toBeVisible() + }) + + test('10.2.2.2 Change gender', async () => { + await page + .locator('#deceased-content #Sex') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#gender')).toBeTruthy() + + await page.locator('#gender').click() + await page.getByText(updatedDeceasedDetails.gender).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Sex').getByRole('deletion') + ).toHaveText(declaration.deceased.gender, { ignoreCase: true }) + + await expect( + page + .locator('#deceased-content #Sex') + .getByText(updatedDeceasedDetails.gender) + ).toBeVisible() + }) + + test('10.2.2.3 Change date of birth', async () => { + await page + .locator('#deceased-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedBirthDate')).toBeTruthy() + + const birthDay = updatedDeceasedDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#deceased-content #Date') + .getByText( + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('10.2.2.4 Change nationality', async () => { + await page + .locator('#deceased-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedDeceasedDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#deceased-content #Nationality') + .getByText(updatedDeceasedDetails.nationality) + ).toBeVisible() + }) + + test('10.2.2.5 Change id type', async () => { + await page + .locator('#deceased-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedIdType')).toBeTruthy() + + await page.locator('#deceasedIdType').click() + await page.getByText(updatedDeceasedDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#deceased-content #Type') + .getByText(updatedDeceasedDetails.idType) + ).toBeVisible() + }) + + test('10.2.2.6 Change id', async () => { + await page + .locator('#deceased-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#deceasedPassport')).toBeTruthy() + + await page.locator('#deceasedPassport').fill(updatedDeceasedDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#deceased-content #ID') + .getByText(updatedDeceasedDetails.id) + ).toBeVisible() + }) + + test('10.2.2.7 Change usual place of residence', async () => { + await page + .locator('#deceased-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryDeceased').click() + await page.getByText(updatedDeceasedDetails.address.province).click() + + await page.locator('#districtPrimaryDeceased').click() + await page.getByText(updatedDeceasedDetails.address.district).click() + + await page + .locator('#cityPrimaryDeceased') + .fill(updatedDeceasedDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryDeceased') + .fill(updatedDeceasedDetails.address.number) + + await page + .locator('#postalCodePrimaryDeceased') + .fill(updatedDeceasedDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Sulaka', { ignoreCase: true }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Zobwe', { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.deceased.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.deceased.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.deceased.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.deceased.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#deceased-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.deceased.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#deceased-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#deceased-content #Usual') + .getByText(updatedDeceasedDetails.address.zipCode) + ).toBeVisible() + }) + + test('10.2.2.8 Change marital status', async () => { + await page + .locator('#deceased-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedDeceasedDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#deceased-content #Marital').getByRole('deletion') + ).toHaveText('-') + + await expect( + page + .locator('#deceased-content #Marital') + .getByText(updatedDeceasedDetails.maritalStatus) + ).toBeVisible() + }) + + test('10.2.2.9 Change number of depandants', async () => { + await page + .getByRole('row', { name: 'No. of dependants' }) + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to deceased's details page + * - focus on deceased's number of depandants + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('deceased-view-group')).toBeTruthy() + expect(page.url().includes('#numberOfDependants')).toBeTruthy() + + await page + .locator('#numberOfDependants') + .fill(updatedDeceasedDetails.NOdependants) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show new number of depandants + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .getByRole('row', { name: 'No. of dependants' }) + .getByText(updatedDeceasedDetails.NOdependants) + ).toBeVisible() + }) + }) + + test('18.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('No supporting documents required').check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('18.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Requested to do so by the court (Judicial order)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('18.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Deceased)' + + declaration.deceased.name[0].firstNames + + ' ' + + declaration.deceased.name[0].familyName + + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Deceased)' + + declaration.deceased.gender + + updatedDeceasedDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Deceased)' + + format(parseISO(declaration.deceased.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedDeceasedDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Deceased)Farajaland' + updatedDeceasedDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Deceased)National ID' + updatedDeceasedDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Deceased)-' + updatedDeceasedDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Deceased)FarajalandSulakaZobwe-' + + declaration.deceased.address[0].city + + declaration.deceased.address[0].line[2] + + declaration.deceased.address[0].line[1] + + declaration.deceased.address[0].line[0] + + declaration.deceased.address[0].postalCode + + 'Farajaland' + + updatedDeceasedDetails.address.province + + updatedDeceasedDetails.address.district + + updatedDeceasedDetails.address.town + + updatedDeceasedDetails.address.residentialArea + + updatedDeceasedDetails.address.street + + updatedDeceasedDetails.address.number + + updatedDeceasedDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Deceased)-' + updatedDeceasedDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'No. of dependants (Deceased)-' + updatedDeceasedDetails.NOdependants + ) + ).toBeVisible() + await expect(page.getByText('Court', { exact: true })).toBeVisible() + + await expect( + page.getByText('Requested to do so by the court (Judicial order)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + ).toBeVisible() + }) + test('18.8 Validate history in record audit', async () => { + await page + .getByText( + updatedDeceasedDetails.firstNames + + ' ' + + updatedDeceasedDetails.familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-2.spec.ts b/e2e/testcases/applications/correction/correct-record-2.spec.ts new file mode 100644 index 000000000..35d087cfb --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-2.spec.ts @@ -0,0 +1,996 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 2', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + + const updatedInformantDetails = { + relationship: 'Sister', + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('2.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('f.katongo', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test('2.1 Certificate preview', async () => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'No, make correction' }).click() + }) + + test('2.2 Correction requester: father', async () => { + await page.getByLabel('Father').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('2.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * ID + * First Name + * Last Name + * Date of Birth + * Nationality + */ + await expect( + page.getByText(`ID: National Id | ${declaration.father.identifier[0].id}`) + ).toBeVisible() + await expect( + page.getByText(`First name(s): ${declaration.father.name[0].firstNames}`) + ).toBeVisible() + await expect( + page.getByText(`Last name: ${declaration.father.name[0].familyName}`) + ).toBeVisible() + await expect( + page.getByText( + `Date of Birth: + ${format(parseISO(declaration.father.birthDate), 'dd MMMM yyyy')} + ` + ) + ).toBeVisible() + await expect( + page.getByText(`Nationality: ${declaration.father.nationality}`) + ).toBeVisible() + + await page.getByRole('button', { name: 'Identity does not match' }).click() + + /* + * Expected result: should show modal with + * - Correct without proof of ID? + * - Please be aware that if you proceed, you will be responsible + * for making a change to this record without the necessary proof of identification + * - Confirm button + * - Cancel button + */ + await expect(page.getByText('Correct without proof of ID?')).toBeVisible() + await expect( + page.getByText( + 'Please be aware that if you proceed, you will be responsible for making a change to this record without the necessary proof of identification' + ) + ).toBeVisible() + await expect(page.getByRole('button', { name: 'Confirm' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('2.4 Correction made on informant details', async () => { + test('2.4.1 Change relationship to child', async () => { + await page + .locator('#informant-content #Relationship') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informantType + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantType')).toBeTruthy() + + await page.locator('#informantType').click() + await page.getByText(updatedInformantDetails.relationship).click() + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous relation with strikethrough + * - show updated relation + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Relationship').getByRole('deletion') + ).toHaveText(declaration.registration.informantType, { ignoreCase: true }) + + await expect( + page + .locator('#informant-content #Relationship') + .getByText(updatedInformantDetails.relationship) + ).toBeVisible() + }) + + test('2.4.2 Change name', async () => { + await page + .locator('#informant-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + // expect(page.url().includes('#familyNameEng')).toBeTruthy() // fail: does not focus on infirmant's family name + + await page + .locator('#firstNamesEng') + .fill(updatedInformantDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedInformantDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#informant-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.informant.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.informant.name[0].familyName + ) + + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.familyName) + ).toBeVisible() + }) + + test('2.4.3 Change date of birth', async () => { + await page + .locator('#informant-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantBirthDate')).toBeTruthy() + + const birthDay = updatedInformantDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#informant-content #Date') + .getByText( + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('2.4.4 Change nationality', async () => { + await page + .locator('#informant-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedInformantDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Nationality') + .getByText(updatedInformantDetails.nationality) + ).toBeVisible() + }) + + test('2.4.5 Change id type', async () => { + await page + .locator('#informant-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantIdType')).toBeTruthy() + + await page.locator('#informantIdType').click() + await page.getByText(updatedInformantDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Type') + .getByText(updatedInformantDetails.idType) + ).toBeVisible() + }) + + test('2.4.6 Change id', async () => { + await page + .locator('#informant-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantPassport')).toBeTruthy() + + await page.locator('#informantPassport').fill(updatedInformantDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#informant-content #ID') + .getByText(updatedInformantDetails.id) + ).toBeVisible() + }) + + test('2.4.7 Change usual place of residence', async () => { + await page + .locator('#informant-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.province).click() + + await page.locator('#districtPrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.district).click() + + await page + .locator('#cityPrimaryInformant') + .fill(updatedInformantDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.number) + + await page + .locator('#postalCodePrimaryInformant') + .fill(updatedInformantDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.informant.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.informant.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.informant.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.informant.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.informant.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#informant-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.zipCode) + ).toBeVisible() + }) + + test('2.4.8 Change email', async () => { + await page + .locator('#informant-content #Email') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#registrationEmail')).toBeTruthy() + + await page + .locator('#registrationEmail') + .fill(updatedInformantDetails.email) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Email with strikethrough + * - show updated Email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Email').getByRole('deletion') + ).toHaveText(declaration.registration.contactEmail, { ignoreCase: true }) + + await expect( + page + .locator('#informant-content #Email') + .getByText(updatedInformantDetails.email) + ).toBeVisible() + }) + }) + + test('2.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'I attest to seeing supporting documentation and have a copy filed at my office' + ) + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('2.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Informant provided incorrect information (Material error)') + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('2.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Send for approval button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Send for approval' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Relationship to child (Informant)' + + declaration.informant.relationship + + updatedInformantDetails.relationship + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Informant)National ID' + updatedInformantDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandCentralIbombo-' + + declaration.informant.address[0].city + + declaration.informant.address[0].line[2] + + declaration.informant.address[0].line[1] + + declaration.informant.address[0].line[0] + + declaration.informant.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + + await expect( + page.getByText( + declaration.father.name[0].firstNames + + ' ' + + declaration.father.name[0].familyName + ) + ).toBeVisible() + await expect(page.getByText('Identity does not match')).toBeVisible() + await expect( + page.getByText( + 'Informant provided incorrect information (Material error)' + ) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Send for approval button + */ + await page.getByRole('button', { name: 'Send for approval' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should + * - be navigated to sent for approval tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/approvals')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + test.describe('2.8 Correction Approval', async () => { + test.beforeAll(async ({ browser }) => { + await page.close() + + page = await browser.newPage() + + await login(page, 'k.mweene', 'test') + await createPIN(page) + }) + + test('2.8.1 Record audit by local registrar', async () => { + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + await page.locator('#name_0').click() + }) + + test('2.8.2 Correction review', async () => { + await page.getByRole('button', { name: 'Review', exact: true }).click() + + /* + * Expected result: should show + * - Submitter + * - Requested by + * - Reason for request + * - Comments + * - Original vs correction + */ + + await expect(page.getByText('Submitter' + 'Felix Katongo')).toBeVisible() + + await expect( + page.getByText( + 'Requested by' + + declaration.father.name[0].firstNames + + ' ' + + declaration.father.name[0].familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Reason for request' + + 'Informant provided incorrect information (Material error)' + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Relationship to child (Informant)' + + declaration.informant.relationship + + updatedInformantDetails.relationship + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Informant)National ID' + updatedInformantDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandCentralIbombo-' + + declaration.informant.address[0].city + + declaration.informant.address[0].line[2] + + declaration.informant.address[0].line[1] + + declaration.informant.address[0].line[0] + + declaration.informant.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + }) + + test('2.8.3 Reject correction', async () => { + await page.getByRole('button', { name: 'Reject', exact: true }).click() + await page + .locator('#rejectionRaisonOfCorrection') + .fill('Wrong information') + await page.getByRole('button', { name: 'Confirm', exact: true }).click() + + await page.waitForTimeout(500) + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the updated declaration in this tab + */ + expect(page.url().includes('registration-home/print')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + + test('2.8.4 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Correction requested + * - Correction rejected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction requested' }) + ).toBeVisible() + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction rejected' }) + ).toBeVisible() + }) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-3.spec.ts b/e2e/testcases/applications/correction/correct-record-3.spec.ts new file mode 100644 index 000000000..08b742370 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-3.spec.ts @@ -0,0 +1,1015 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 3', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + + const updatedMotherDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + educationLevel: 'Primary' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('3.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('f.katongo', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test.describe('3.1 Print > Ready to issue', async () => { + test('3.1.1 Print', async () => { + await login(page, 'f.katongo', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'Yes, print certificate' }).click() + await page.getByRole('button', { name: 'Print', exact: true }).click() + }) + + test('3.1.2 Ready to issue', async () => { + await page.getByRole('button', { name: 'Ready to issue' }).click() + + /* + * Expected result: should + * - be navigated to ready to isssue tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/readyToIssue')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + + test('3.1.3 Record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show correct record button + */ + await expect( + page.getByRole('button', { name: 'Correct record', exact: true }) + ).toBeVisible() + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + }) + + test('3.2 Correction requester: child', async () => { + await page.getByLabel('Child').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('3.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * First Name + * Last Name + * Date of Birth + */ + await expect( + page.getByText(`First name(s): ${declaration.child.name[0].firstNames}`) + ).toBeVisible() + await expect( + page.getByText(`Last name: ${declaration.child.name[0].familyName}`) + ).toBeVisible() + await expect( + page.getByText( + `Date of Birth: + ${format(parseISO(declaration.child.birthDate), 'dd MMMM yyyy')} + ` + ) + ).toBeVisible() + + await page.getByRole('button', { name: 'Verified' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('3.4 Correction made on mother details', async () => { + test('3.4.1 Change name', async () => { + await page + .locator('#mother-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedMotherDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedMotherDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#mother-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.mother.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.mother.name[0].familyName) + + await expect( + page + .locator('#mother-content #Full') + .getByText(updatedMotherDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Full') + .getByText(updatedMotherDetails.familyName) + ).toBeVisible() + }) + + test('3.4.2 Change date of birth', async () => { + await page + .locator('#mother-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#motherBirthDate')).toBeTruthy() + + const birthDay = updatedMotherDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.mother.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#mother-content #Date') + .getByText( + format(parseISO(updatedMotherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('3.4.3 Change nationality', async () => { + await page + .locator('#mother-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedMotherDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Nationality') + .getByText(updatedMotherDetails.nationality) + ).toBeVisible() + }) + + test('3.4.4 Change id type', async () => { + await page + .locator('#mother-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#motherIdType')).toBeTruthy() + + await page.locator('#motherIdType').click() + await page.getByText(updatedMotherDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Type') + .getByText(updatedMotherDetails.idType) + ).toBeVisible() + }) + + test('3.4.5 Change id', async () => { + await page + .locator('#mother-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#motherPassport')).toBeTruthy() + + await page.locator('#motherPassport').fill(updatedMotherDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #ID').getByText(updatedMotherDetails.id) + ).toBeVisible() + }) + + test('3.4.6 Change usual place of residence', async () => { + await page + .locator('#mother-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryMother').click() + await page.getByText(updatedMotherDetails.address.province).click() + + await page.locator('#districtPrimaryMother').click() + await page.getByText(updatedMotherDetails.address.district).click() + + await page + .locator('#cityPrimaryMother') + .fill(updatedMotherDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryMother') + .fill(updatedMotherDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryMother') + .fill(updatedMotherDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryMother') + .fill(updatedMotherDetails.address.number) + + await page + .locator('#postalCodePrimaryMother') + .fill(updatedMotherDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.mother.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.mother.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.mother.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.mother.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.mother.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#mother-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.zipCode) + ).toBeVisible() + }) + + test('3.4.7 Change marital status', async () => { + await page + .locator('#mother-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedMotherDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Marital').getByRole('deletion') + ).toHaveText(declaration.mother.maritalStatus, { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Marital') + .getByText(updatedMotherDetails.maritalStatus) + ).toBeVisible() + }) + + test('3.4.8 Change level of education', async () => { + await page + .locator('#mother-content #Level') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#educationalAttainment')).toBeTruthy() + + await page.locator('#educationalAttainment').click() + await page.getByText(updatedMotherDetails.educationLevel).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous level of education with strikethrough + * - show updated level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Level').getByRole('deletion') + ).toHaveText('No Schooling', { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Level') + .getByText(updatedMotherDetails.educationLevel) + ).toBeVisible() + }) + }) + + test('3.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('No supporting documents required').check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('3.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'Informant did not provide this information (Material omission)' + ) + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('3.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Send for approval button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Send for approval' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (mother)' + + declaration.mother.name[0].firstNames + + ' ' + + declaration.mother.name[0].familyName + + updatedMotherDetails.firstNames + + ' ' + + updatedMotherDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (mother)' + + format(parseISO(declaration.mother.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedMotherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Mother)Farajaland' + updatedMotherDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Mother)National ID' + updatedMotherDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Mother)-' + updatedMotherDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Mother)FarajalandCentralIbombo-' + + declaration.mother.address[0].city + + declaration.mother.address[0].line[2] + + declaration.mother.address[0].line[1] + + declaration.mother.address[0].line[0] + + declaration.mother.address[0].postalCode + + 'Farajaland' + + updatedMotherDetails.address.province + + updatedMotherDetails.address.district + + updatedMotherDetails.address.town + + updatedMotherDetails.address.residentialArea + + updatedMotherDetails.address.street + + updatedMotherDetails.address.number + + updatedMotherDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Mother)' + + declaration.mother.maritalStatus + + updatedMotherDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Level of education (Mother)No schooling' + + updatedMotherDetails.educationLevel + ) + ).toBeVisible() + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + await expect(page.getByText('Verified')).toBeVisible() + await expect( + page.getByText( + 'Informant did not provide this information (Material omission)' + ) + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Send for approval button + */ + await page.getByRole('button', { name: 'Send for approval' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should + * - be navigated to sent for approval tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/approvals')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + + test.describe('3.8 Correction Approval', async () => { + test.beforeAll(async ({ browser }) => { + await page.close() + + page = await browser.newPage() + + await login(page, 'k.mweene', 'test') + await createPIN(page) + }) + + test('3.8.1 Record audit by local registrar', async () => { + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + await page.locator('#name_0').click() + }) + + test('3.8.2 Correction review', async () => { + await page.getByRole('button', { name: 'Review', exact: true }).click() + + /* + * Expected result: should show + * - Submitter + * - Requested by + * - Reason for request + * - Comments + * - Original vs correction + */ + + await expect(page.getByText('Submitter' + 'Felix Katongo')).toBeVisible() + + await expect( + page.getByText( + 'Requested by' + + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + await expect( + page.getByText( + 'Reason for request' + + 'Informant did not provide this information (Material omission)' + ) + ).toBeVisible() + + await expect( + page.getByText('Comments' + declaration.registration.registrationNumber) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (mother)' + + declaration.mother.name[0].firstNames + + ' ' + + declaration.mother.name[0].familyName + + updatedMotherDetails.firstNames + + ' ' + + updatedMotherDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (mother)' + + format(parseISO(declaration.mother.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedMotherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Mother)Farajaland' + updatedMotherDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Mother)National ID' + updatedMotherDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Mother)-' + updatedMotherDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Mother)FarajalandCentralIbombo-' + + declaration.mother.address[0].city + + declaration.mother.address[0].line[2] + + declaration.mother.address[0].line[1] + + declaration.mother.address[0].line[0] + + declaration.mother.address[0].postalCode + + 'Farajaland' + + updatedMotherDetails.address.province + + updatedMotherDetails.address.district + + updatedMotherDetails.address.town + + updatedMotherDetails.address.residentialArea + + updatedMotherDetails.address.street + + updatedMotherDetails.address.number + + updatedMotherDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Mother)' + + declaration.mother.maritalStatus + + updatedMotherDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Level of education (Mother)No schooling' + + updatedMotherDetails.educationLevel + ) + ).toBeVisible() + }) + + test('3.8.3 Approve correction', async () => { + await page.getByRole('button', { name: 'Approve', exact: true }).click() + await page.getByRole('button', { name: 'Confirm', exact: true }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the updated declaration in this tab + */ + expect(page.url().includes('registration-home/print')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + + test('3.8.4 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Correction requested + * - Correction approved + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction requested' }) + ).toBeVisible() + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Correction approved' }) + ).toBeVisible() + }) + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-4.spec.ts b/e2e/testcases/applications/correction/correct-record-4.spec.ts new file mode 100644 index 000000000..c012906af --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-4.spec.ts @@ -0,0 +1,800 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login, uploadImage } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 4', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + + const updatedFatherDetails = { + firstNames: faker.name.firstName('male'), + familyName: faker.name.firstName('male'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + educationLevel: 'Primary' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('4.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('k.mweene', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test('4.1 Ready to print > record audit', async () => { + await login(page, 'k.mweene', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + + test('4.2 Correction requester: legal guardian', async () => { + await page.getByLabel('Legal guardian').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('4.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * nothing + */ + + await page.getByRole('button', { name: 'Verified' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('4.4 Correction made on father details', async () => { + test('4.4.1 Change name', async () => { + await page + .locator('#father-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedFatherDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedFatherDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#father-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.father.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.father.name[0].familyName) + + await expect( + page + .locator('#father-content #Full') + .getByText(updatedFatherDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#father-content #Full') + .getByText(updatedFatherDetails.familyName) + ).toBeVisible() + }) + + test('4.4.2 Change date of birth', async () => { + await page + .locator('#father-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#fatherBirthDate')).toBeTruthy() + + const birthDay = updatedFatherDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.father.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#father-content #Date') + .getByText( + format(parseISO(updatedFatherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('4.4.3 Change nationality', async () => { + await page + .locator('#father-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedFatherDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Nationality') + .getByText(updatedFatherDetails.nationality) + ).toBeVisible() + }) + + test('4.4.4 Change id type', async () => { + await page + .locator('#father-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#fatherIdType')).toBeTruthy() + + await page.locator('#fatherIdType').click() + await page.getByText(updatedFatherDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Type') + .getByText(updatedFatherDetails.idType) + ).toBeVisible() + }) + + test('4.4.5 Change id', async () => { + await page + .locator('#father-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#fatherPassport')).toBeTruthy() + + await page.locator('#fatherPassport').fill(updatedFatherDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #ID').getByText(updatedFatherDetails.id) + ).toBeVisible() + }) + + test('4.4.6 Change usual place of residence', async () => { + await page + .locator('#father-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryFather').click() + await page.getByText(updatedFatherDetails.address.province).click() + + await page.locator('#districtPrimaryFather').click() + await page.getByText(updatedFatherDetails.address.district).click() + + await page + .locator('#cityPrimaryFather') + .fill(updatedFatherDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryFather') + .fill(updatedFatherDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryFather') + .fill(updatedFatherDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryFather') + .fill(updatedFatherDetails.address.number) + + await page + .locator('#postalCodePrimaryFather') + .fill(updatedFatherDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.father.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.father.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.father.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.father.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.father.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#father-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.zipCode) + ).toBeVisible() + }) + + test('4.4.7 Change marital status', async () => { + await page + .locator('#father-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedFatherDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Marital').getByRole('deletion') + ).toHaveText(declaration.father.maritalStatus, { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Marital') + .getByText(updatedFatherDetails.maritalStatus) + ).toBeVisible() + }) + + test('4.4.8 Change level of education', async () => { + await page + .locator('#father-content #Level') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#educationalAttainment')).toBeTruthy() + + await page.locator('#educationalAttainment').click() + await page.getByText(updatedFatherDetails.educationLevel).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous level of education with strikethrough + * - show updated level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Level').getByRole('deletion') + ).toHaveText('No Schooling', { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Level') + .getByText(updatedFatherDetails.educationLevel) + ).toBeVisible() + }) + }) + + test('4.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByText('Select...').click() + await page.getByText('Affidavit', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Court Document', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Other', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('4.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Requested to do so by the court (Judicial order)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('4.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (father)' + + declaration.father.name[0].firstNames + + ' ' + + declaration.father.name[0].familyName + + updatedFatherDetails.firstNames + + ' ' + + updatedFatherDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (father)' + + format(parseISO(declaration.father.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedFatherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Father)Farajaland' + updatedFatherDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Father)National ID' + updatedFatherDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Father)-' + updatedFatherDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Father)FarajalandCentralIbombo-' + + declaration.father.address[0].city + + declaration.father.address[0].line[2] + + declaration.father.address[0].line[1] + + declaration.father.address[0].line[0] + + declaration.father.address[0].postalCode + + 'Farajaland' + + updatedFatherDetails.address.province + + updatedFatherDetails.address.district + + updatedFatherDetails.address.town + + updatedFatherDetails.address.residentialArea + + updatedFatherDetails.address.street + + updatedFatherDetails.address.number + + updatedFatherDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Father)' + + declaration.father.maritalStatus + + updatedFatherDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Level of education (Father)No schooling' + + updatedFatherDetails.educationLevel + ) + ).toBeVisible() + + await expect(page.getByText('Legal guardian')).toBeVisible() + await expect(page.getByText('Verified')).toBeVisible() + await expect( + page.getByText('Requested to do so by the court (Judicial order)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('Yes').check() + await page.locator('#correctionFees\\.nestedFields\\.totalFees').fill('15') + + await uploadImage(page, page.locator('#upload_document')) + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + test('4.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-5.spec.ts b/e2e/testcases/applications/correction/correct-record-5.spec.ts new file mode 100644 index 000000000..ce6f3eef1 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-5.spec.ts @@ -0,0 +1,649 @@ +import { expect, test, type Page } from '@playwright/test' +import { + createPIN, + getLocationNameFromFhirId, + getToken, + login +} from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 5', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let childBirthLocationName: string | undefined + + let page: Page + const updatedChildDetails = { + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + gender: 'Female', + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random())), + 'yyyy-MM-dd' + ), + placeOfBirth: 'Tembwe Rural Health Centre', + attendantAtBirth: 'Nurse', + typeOfBirth: 'Twin', + weightAtBirth: '3.1', + reason: 'Change of mind' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('5.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('k.mweene', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test('5.1 Certificate preview', async () => { + await login(page, 'k.mweene', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'No, make correction' }).click() + }) + + test('5.2 Correction requester: another registration agent or field agent', async () => { + await page.getByLabel('Another registration agent or field agent').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('5.3 Verify identity', async () => { + /* + * Expected result: + * - should not show verify identity + * - should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('5.4.2 Correction made on child details', async () => { + test('5.4.2.1 Change name', async () => { + await page + .locator('#child-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedChildDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedChildDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#child-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.child.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.child.name[0].familyName) + + await expect( + page + .locator('#child-content #Full') + .getByText(updatedChildDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#child-content #Full') + .getByText(updatedChildDetails.familyName) + ).toBeVisible() + }) + + test('5.4.2.2 Change gender', async () => { + await page + .locator('#child-content #Sex') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#gender')).toBeTruthy() + + await page.locator('#gender').click() + await page.getByText(updatedChildDetails.gender).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#child-content #Sex').getByRole('deletion') + ).toHaveText(declaration.child.gender, { ignoreCase: true }) + + await expect( + page + .locator('#child-content #Sex') + .getByText(updatedChildDetails.gender) + ).toBeVisible() + }) + + test('5.4.2.3 Change date of birth', async () => { + await page + .locator('#child-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#childBirthDate')).toBeTruthy() + + const birthDay = updatedChildDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous date of birth with strikethrough + * - show updated date of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#child-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.child.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#child-content #Date') + .getByText( + format(parseISO(updatedChildDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('5.4.2.4 Change place of delivery', async () => { + await page + .locator('#child-content #Place') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's place of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#placeOfBirth')).toBeTruthy() + + await page + .locator('#birthLocation') + .fill(updatedChildDetails.placeOfBirth.slice(0, 2)) + await page.getByText(updatedChildDetails.placeOfBirth).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous place of birth with strikethrough + * - show updated place of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.eventLocation).toBeDefined() + + childBirthLocationName = await getLocationNameFromFhirId( + declaration.eventLocation!.id + ) + expect(childBirthLocationName).toBeDefined() + + await expect( + page.locator('#child-content #Place').getByRole('deletion').nth(1) + ).toHaveText(childBirthLocationName!, { + ignoreCase: true + }) + + await expect( + page + .locator('#child-content #Place') + .getByText(updatedChildDetails.placeOfBirth) + ).toBeVisible() + }) + + test('5.4.2.5 Change attendant at birth', async () => { + await page + .locator('#child-content #Attendant') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's Attendant at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#attendantAtBirth')).toBeTruthy() + + await page.locator('#attendantAtBirth').click() + await page.getByText(updatedChildDetails.attendantAtBirth).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Attendant at birth with strikethrough + * - show updated Attendant at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.attendantAtBirth).toBeDefined + + await expect( + page.locator('#child-content #Attendant').getByRole('deletion') + ).toHaveText(declaration.attendantAtBirth!, { ignoreCase: true }) + + await expect( + page + .locator('#child-content #Attendant') + .getByText(updatedChildDetails.attendantAtBirth) + ).toBeVisible() + }) + + test('5.4.2.6 Change type of birth', async () => { + await page + .locator('#child-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's type of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#birthType')).toBeTruthy() + + await page.locator('#birthType').click() + await page.getByText(updatedChildDetails.typeOfBirth).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous type of birth with strikethrough + * - show updated type of birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.birthType).toBeDefined + + await expect( + page.locator('#child-content #Type').getByRole('deletion') + ).toHaveText(declaration.birthType!, { ignoreCase: true }) + + await expect( + page + .locator('#child-content #Type') + .getByText(updatedChildDetails.typeOfBirth) + ).toBeVisible() + }) + + test('5.4.2.7 Change weight at birth', async () => { + await page + .locator('#child-content #Weight') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to child's details page + * - focus on child's weight at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('child-view-group')).toBeTruthy() + expect(page.url().includes('#weightAtBirth')).toBeTruthy() + + await page + .locator('#weightAtBirth') + .fill(updatedChildDetails.weightAtBirth) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous weight at birth with strikethrough + * - show updated weight at birth + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + expect(declaration.weightAtBirth).toBeDefined + + await expect( + page.locator('#child-content #Weight').getByRole('deletion') + ).toHaveText(declaration.weightAtBirth! + ' kilograms (kg)') + + await expect( + page + .locator('#child-content #Weight') + .getByText(updatedChildDetails.weightAtBirth + ' kilograms (kg)') + ).toBeVisible() + }) + }) + + test('5.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'I attest to seeing supporting documentation and have a copy filed at my office' + ) + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('5.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('Other').check() + await page + .locator('#type\\.nestedFields\\.otherReason') + .fill(updatedChildDetails.reason) + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('5.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (Child)' + + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + + updatedChildDetails.firstNames + + ' ' + + updatedChildDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Sex (Child)' + declaration.child.gender + updatedChildDetails.gender + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (Child)' + + format(parseISO(declaration.child.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedChildDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Place of delivery (Child)' + + 'Health Institution' + + childBirthLocationName + + 'Health Institution' + + updatedChildDetails.placeOfBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Attendant at birth (Child)' + + declaration.attendantAtBirth + + updatedChildDetails.attendantAtBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of birth (Child)' + + declaration.birthType + + updatedChildDetails.typeOfBirth + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Weight at birth (Child)' + + declaration.weightAtBirth + + updatedChildDetails.weightAtBirth + ) + ).toBeVisible() + + await expect( + page.getByText('Another registration agent or field agent') + ).toBeVisible() + await expect(page.getByText(updatedChildDetails.reason)).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + updatedChildDetails.firstNames + ' ' + updatedChildDetails.familyName + ) + ).toBeVisible() + }) + test('5.8 Validate history in record audit', async () => { + await page + .getByText( + updatedChildDetails.firstNames + ' ' + updatedChildDetails.familyName + ) + .click() + + await page.getByLabel('Assign record').click() + + if (await page.getByText('Unassign record?', { exact: true }).isVisible()) + await page.getByRole('button', { name: 'Cancel', exact: true }).click() + else if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-6.spec.ts b/e2e/testcases/applications/correction/correct-record-6.spec.ts new file mode 100644 index 000000000..b49aaa938 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-6.spec.ts @@ -0,0 +1,826 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 6', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + const updatedInformantDetails = { + relationship: 'Sister', + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('6.0 Shortcut declaration', async () => { + let token = await getToken('k.mweene', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('k.mweene', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test.describe('6.1 Print > Ready to issue', async () => { + test('6.1.1 print', async () => { + await login(page, 'k.mweene', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'Yes, print certificate' }).click() + await page.getByRole('button', { name: 'Print', exact: true }).click() + }) + test('6.1.2 Ready to issue', async () => { + await page.getByRole('button', { name: 'Ready to issue' }).click() + + /* + * Expected result: should + * - be navigated to ready to isssue tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/readyToIssue')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + }) + test('6.1.3 Record audit', async () => { + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show correct record button + */ + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + }) + + test('6.2 Correction requester: Me', async () => { + await page.getByLabel('Me', { exact: true }).check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('6.3 Verify identity', async () => { + /* + * Expected result: + * - should not show verify identity + * - should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('6.4 Correction made on informant details', async () => { + test('6.4.1 Change relationship to child', async () => { + await page + .locator('#informant-content #Relationship') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informantType + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantType')).toBeTruthy() + + await page.locator('#informantType').click() + await page.getByText(updatedInformantDetails.relationship).click() + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous relation with strikethrough + * - show updated relation + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Relationship').getByRole('deletion') + ).toHaveText(declaration.registration.informantType, { ignoreCase: true }) + + await expect( + page + .locator('#informant-content #Relationship') + .getByText(updatedInformantDetails.relationship) + ).toBeVisible() + }) + + test('6.4.2 Change name', async () => { + await page + .locator('#informant-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + // expect(page.url().includes('#familyNameEng')).toBeTruthy() // fail: does not focus on infirmant's family name + + await page + .locator('#firstNamesEng') + .fill(updatedInformantDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedInformantDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#informant-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.informant.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.informant.name[0].familyName + ) + + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.familyName) + ).toBeVisible() + }) + + test('6.4.3 Change date of birth', async () => { + await page + .locator('#informant-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantBirthDate')).toBeTruthy() + + const birthDay = updatedInformantDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#informant-content #Date') + .getByText( + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('6.4.4 Change nationality', async () => { + await page + .locator('#informant-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedInformantDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Nationality') + .getByText(updatedInformantDetails.nationality) + ).toBeVisible() + }) + + test('6.4.5 Change id type', async () => { + await page + .locator('#informant-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantIdType')).toBeTruthy() + + await page.locator('#informantIdType').click() + await page.getByText(updatedInformantDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Type') + .getByText(updatedInformantDetails.idType) + ).toBeVisible() + }) + + test('6.4.6 Change id', async () => { + await page + .locator('#informant-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantPassport')).toBeTruthy() + + await page.locator('#informantPassport').fill(updatedInformantDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#informant-content #ID') + .getByText(updatedInformantDetails.id) + ).toBeVisible() + }) + + test('6.4.7 Change usual place of residence', async () => { + await page + .locator('#informant-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.province).click() + + await page.locator('#districtPrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.district).click() + + await page + .locator('#cityPrimaryInformant') + .fill(updatedInformantDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.number) + + await page + .locator('#postalCodePrimaryInformant') + .fill(updatedInformantDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.informant.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.informant.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.informant.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.informant.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.informant.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#informant-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.zipCode) + ).toBeVisible() + }) + + test('6.4.8 Change email', async () => { + await page + .locator('#informant-content #Email') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#registrationEmail')).toBeTruthy() + + await page + .locator('#registrationEmail') + .fill(updatedInformantDetails.email) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Email with strikethrough + * - show updated Email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Email').getByRole('deletion') + ).toHaveText(declaration.registration.contactEmail, { ignoreCase: true }) + + await expect( + page + .locator('#informant-content #Email') + .getByText(updatedInformantDetails.email) + ).toBeVisible() + }) + }) + + test('6.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('No supporting documents required').check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('6.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Myself or an agent made a mistake (Clerical error)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('6.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Relationship to child (Informant)' + + declaration.informant.relationship + + updatedInformantDetails.relationship + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Informant)National ID' + updatedInformantDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandCentralIbombo-' + + declaration.informant.address[0].city + + declaration.informant.address[0].line[2] + + declaration.informant.address[0].line[1] + + declaration.informant.address[0].line[0] + + declaration.informant.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + + await expect(page.getByText('Me', { exact: true })).toBeVisible() + await expect( + page.getByText('Myself or an agent made a mistake (Clerical error)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + test('6.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-7.spec.ts b/e2e/testcases/applications/correction/correct-record-7.spec.ts new file mode 100644 index 000000000..7db00ae12 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-7.spec.ts @@ -0,0 +1,817 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login, uploadImage } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 7', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + + const updatedMotherDetails = { + firstNames: faker.name.firstName('male'), + familyName: faker.name.firstName('male'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + educationLevel: 'Primary' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('7.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('j.musonda', 'test') + + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test('7.1 Ready to print > record audit', async () => { + await login(page, 'j.musonda', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + + test('7.2 Correction requester: court', async () => { + await page.getByLabel('Court').check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('7.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * nothing + */ + + await page.getByRole('button', { name: 'Identity does not match' }).click() + + /* + * Expected result: should show modal with + * - Correct without proof of ID? + * - Please be aware that if you proceed, you will be responsible + * for making a change to this record without the necessary proof of identification + * - Confirm button + * - Cancel button + */ + await expect(page.getByText('Correct without proof of ID?')).toBeVisible() + await expect( + page.getByText( + 'Please be aware that if you proceed, you will be responsible for making a change to this record without the necessary proof of identification' + ) + ).toBeVisible() + await expect(page.getByRole('button', { name: 'Confirm' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible() + await page.getByRole('button', { name: 'Confirm' }).click() + + /* + * Expected result: should navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('7.4 Correction made on mother details', async () => { + test('7.4.1 Change name', async () => { + await page + .locator('#mother-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedMotherDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedMotherDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#mother-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.mother.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.mother.name[0].familyName) + + await expect( + page + .locator('#mother-content #Full') + .getByText(updatedMotherDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Full') + .getByText(updatedMotherDetails.familyName) + ).toBeVisible() + }) + + test('7.4.2 Change date of birth', async () => { + await page + .locator('#mother-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#motherBirthDate')).toBeTruthy() + + const birthDay = updatedMotherDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.mother.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#mother-content #Date') + .getByText( + format(parseISO(updatedMotherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('7.4.3 Change nationality', async () => { + await page + .locator('#mother-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedMotherDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Nationality') + .getByText(updatedMotherDetails.nationality) + ).toBeVisible() + }) + + test('7.4.4 Change id type', async () => { + await page + .locator('#mother-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#motherIdType')).toBeTruthy() + + await page.locator('#motherIdType').click() + await page.getByText(updatedMotherDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Type') + .getByText(updatedMotherDetails.idType) + ).toBeVisible() + }) + + test('7.4.5 Change id', async () => { + await page + .locator('#mother-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#motherPassport')).toBeTruthy() + + await page.locator('#motherPassport').fill(updatedMotherDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #ID').getByText(updatedMotherDetails.id) + ).toBeVisible() + }) + + test('7.4.6 Change usual place of residence', async () => { + await page + .locator('#mother-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryMother').click() + await page.getByText(updatedMotherDetails.address.province).click() + + await page.locator('#districtPrimaryMother').click() + await page.getByText(updatedMotherDetails.address.district).click() + + await page + .locator('#cityPrimaryMother') + .fill(updatedMotherDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryMother') + .fill(updatedMotherDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryMother') + .fill(updatedMotherDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryMother') + .fill(updatedMotherDetails.address.number) + + await page + .locator('#postalCodePrimaryMother') + .fill(updatedMotherDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.mother.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.mother.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.mother.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.mother.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#mother-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.mother.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#mother-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#mother-content #Usual') + .getByText(updatedMotherDetails.address.zipCode) + ).toBeVisible() + }) + + test('7.4.7 Change marital status', async () => { + await page + .locator('#mother-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedMotherDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Marital').getByRole('deletion') + ).toHaveText(declaration.mother.maritalStatus, { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Marital') + .getByText(updatedMotherDetails.maritalStatus) + ).toBeVisible() + }) + + test('7.4.8 Change level of education', async () => { + await page + .locator('#mother-content #Level') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to mother's details page + * - focus on mother's level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('mother-view-group')).toBeTruthy() + expect(page.url().includes('#educationalAttainment')).toBeTruthy() + + await page.locator('#educationalAttainment').click() + await page.getByText(updatedMotherDetails.educationLevel).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous level of education with strikethrough + * - show updated level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#mother-content #Level').getByRole('deletion') + ).toHaveText('No Schooling', { + ignoreCase: true + }) + + await expect( + page + .locator('#mother-content #Level') + .getByText(updatedMotherDetails.educationLevel) + ).toBeVisible() + }) + }) + + test('7.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByText('Select...').click() + await page.getByText('Affidavit', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Court Document', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + + await page.getByText('Select...').click() + await page.getByText('Other', { exact: true }).click() + await uploadImage(page, page.getByRole('button', { name: 'Upload' })) + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('7.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Informant provided incorrect information (Material error)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('7.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (mother)' + + declaration.mother.name[0].firstNames + + ' ' + + declaration.mother.name[0].familyName + + updatedMotherDetails.firstNames + + ' ' + + updatedMotherDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (mother)' + + format(parseISO(declaration.mother.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedMotherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Mother)Farajaland' + updatedMotherDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Mother)National ID' + updatedMotherDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Mother)-' + updatedMotherDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Mother)FarajalandCentralIbombo-' + + declaration.mother.address[0].city + + declaration.mother.address[0].line[2] + + declaration.mother.address[0].line[1] + + declaration.mother.address[0].line[0] + + declaration.mother.address[0].postalCode + + 'Farajaland' + + updatedMotherDetails.address.province + + updatedMotherDetails.address.district + + updatedMotherDetails.address.town + + updatedMotherDetails.address.residentialArea + + updatedMotherDetails.address.street + + updatedMotherDetails.address.number + + updatedMotherDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Mother)' + + declaration.mother.maritalStatus + + updatedMotherDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Level of education (Mother)No schooling' + + updatedMotherDetails.educationLevel + ) + ).toBeVisible() + + await expect(page.getByText('Court', { exact: true })).toBeVisible() + await expect(page.getByText('Identity does not match')).toBeVisible() + await expect( + page.getByText( + 'Informant provided incorrect information (Material error)' + ) + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('Yes').check() + await page.locator('#correctionFees\\.nestedFields\\.totalFees').fill('15') + + await uploadImage(page, page.locator('#upload_document')) + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + test('7.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-8.spec.ts b/e2e/testcases/applications/correction/correct-record-8.spec.ts new file mode 100644 index 000000000..4b88af6c1 --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-8.spec.ts @@ -0,0 +1,791 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 8', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + + const updatedFatherDetails = { + firstNames: faker.name.firstName('male'), + familyName: faker.name.firstName('male'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + }, + maritalStatus: 'Married', + educationLevel: 'Primary' + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('8.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('j.musonda', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test('8.1 Certificate preview', async () => { + await login(page, 'j.musonda', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'No, make correction' }).click() + }) + + test('8.2 Correction requester: someone else (Cousin)', async () => { + await page.getByLabel('Someone else').check() + await page.getByPlaceholder('Eg. Grandmother').fill('Cousin') + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('8.3 Verify identity', async () => { + /* + * Expected result: should Confirm + * nothing + */ + + await page.getByRole('button', { name: 'Verified' }).click() + + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('8.4 Correction made on father details', async () => { + test('8.4.1 Change name', async () => { + await page + .locator('#father-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#familyNameEng')).toBeTruthy() + + await page.locator('#firstNamesEng').fill(updatedFatherDetails.firstNames) + await page.locator('#familyNameEng').fill(updatedFatherDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#father-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText(declaration.father.name[0].firstNames) + await expect(oldData[1]).toHaveText(declaration.father.name[0].familyName) + + await expect( + page + .locator('#father-content #Full') + .getByText(updatedFatherDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#father-content #Full') + .getByText(updatedFatherDetails.familyName) + ).toBeVisible() + }) + + test('8.4.2 Change date of birth', async () => { + await page + .locator('#father-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#fatherBirthDate')).toBeTruthy() + + const birthDay = updatedFatherDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.father.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#father-content #Date') + .getByText( + format(parseISO(updatedFatherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('8.4.3 Change nationality', async () => { + await page + .locator('#father-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedFatherDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Nationality') + .getByText(updatedFatherDetails.nationality) + ).toBeVisible() + }) + + test('8.4.4 Change id type', async () => { + await page + .locator('#father-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#fatherIdType')).toBeTruthy() + + await page.locator('#fatherIdType').click() + await page.getByText(updatedFatherDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Type') + .getByText(updatedFatherDetails.idType) + ).toBeVisible() + }) + + test('8.4.5 Change id', async () => { + await page + .locator('#father-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#fatherPassport')).toBeTruthy() + + await page.locator('#fatherPassport').fill(updatedFatherDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #ID').getByText(updatedFatherDetails.id) + ).toBeVisible() + }) + + test('8.4.6 Change usual place of residence', async () => { + await page + .locator('#father-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryFather').click() + await page.getByText(updatedFatherDetails.address.province).click() + + await page.locator('#districtPrimaryFather').click() + await page.getByText(updatedFatherDetails.address.district).click() + + await page + .locator('#cityPrimaryFather') + .fill(updatedFatherDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryFather') + .fill(updatedFatherDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryFather') + .fill(updatedFatherDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryFather') + .fill(updatedFatherDetails.address.number) + + await page + .locator('#postalCodePrimaryFather') + .fill(updatedFatherDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.father.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.father.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.father.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.father.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#father-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.father.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#father-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#father-content #Usual') + .getByText(updatedFatherDetails.address.zipCode) + ).toBeVisible() + }) + + test('8.4.7 Change marital status', async () => { + await page + .locator('#father-content #Marital') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#maritalStatus')).toBeTruthy() + + await page.locator('#maritalStatus').click() + await page.getByText(updatedFatherDetails.maritalStatus).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous marital status with strikethrough + * - show updated marital status + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Marital').getByRole('deletion') + ).toHaveText(declaration.father.maritalStatus, { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Marital') + .getByText(updatedFatherDetails.maritalStatus) + ).toBeVisible() + }) + + test('8.4.8 Change level of education', async () => { + await page + .locator('#father-content #Level') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to father's details page + * - focus on father's level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('father-view-group')).toBeTruthy() + expect(page.url().includes('#educationalAttainment')).toBeTruthy() + + await page.locator('#educationalAttainment').click() + await page.getByText(updatedFatherDetails.educationLevel).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous level of education with strikethrough + * - show updated level of education + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#father-content #Level').getByRole('deletion') + ).toHaveText('No Schooling', { + ignoreCase: true + }) + + await expect( + page + .locator('#father-content #Level') + .getByText(updatedFatherDetails.educationLevel) + ).toBeVisible() + }) + }) + + test('8.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'I attest to seeing supporting documentation and have a copy filed at my office' + ) + .check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('8.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel( + 'Informant did not provide this information (Material omission)' + ) + .check() + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('8.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Full name (father)' + + declaration.father.name[0].firstNames + + ' ' + + declaration.father.name[0].familyName + + updatedFatherDetails.firstNames + + ' ' + + updatedFatherDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (father)' + + format(parseISO(declaration.father.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedFatherDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Father)Farajaland' + updatedFatherDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Father)National ID' + updatedFatherDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Father)-' + updatedFatherDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Father)FarajalandCentralIbombo-' + + declaration.father.address[0].city + + declaration.father.address[0].line[2] + + declaration.father.address[0].line[1] + + declaration.father.address[0].line[0] + + declaration.father.address[0].postalCode + + 'Farajaland' + + updatedFatherDetails.address.province + + updatedFatherDetails.address.district + + updatedFatherDetails.address.town + + updatedFatherDetails.address.residentialArea + + updatedFatherDetails.address.street + + updatedFatherDetails.address.number + + updatedFatherDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Marital status (Father)' + + declaration.father.maritalStatus + + updatedFatherDetails.maritalStatus + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Level of education (Father)No schooling' + + updatedFatherDetails.educationLevel + ) + ).toBeVisible() + + await expect(page.getByText('Cousin')).toBeVisible() + await expect( + page.getByText( + 'Informant did not provide this information (Material omission)' + ) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + test('8.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + + if (await page.getByText('Unassign record?', { exact: true }).isVisible()) + await page.getByRole('button', { name: 'Cancel', exact: true }).click() + else if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/applications/correction/correct-record-9.spec.ts b/e2e/testcases/applications/correction/correct-record-9.spec.ts new file mode 100644 index 000000000..10a7bf5aa --- /dev/null +++ b/e2e/testcases/applications/correction/correct-record-9.spec.ts @@ -0,0 +1,829 @@ +import { expect, test, type Page } from '@playwright/test' +import { createPIN, getToken, login } from '../../../helpers' +import faker from '@faker-js/faker' +import { + ConvertEnumsToStrings, + createDeclaration, + fetchDeclaration +} from '../../birth/helpers' +import { BirthDeclaration, BirthInputDetails } from '../../birth/types' +import { format, parseISO, subDays } from 'date-fns' + +test.describe.serial(' Correct record - 9', () => { + let declaration: BirthDeclaration + let trackingId = '' + + let page: Page + const updatedInformantDetails = { + relationship: 'Sister', + firstNames: faker.name.firstName('female'), + familyName: faker.name.firstName('female'), + birthDate: format( + subDays(new Date(), Math.ceil(50 * Math.random() + 365 * 25)), + 'yyyy-MM-dd' + ), + email: faker.internet.email(), + nationality: 'Nauru', + id: faker.random.numeric(10), + idType: 'Passport', + address: { + province: 'Sulaka', + district: 'Irundu', + town: faker.address.city(), + residentialArea: faker.address.county(), + street: faker.address.streetName(), + number: faker.address.buildingNumber(), + zipCode: faker.address.zipCode() + } + } + + test.beforeAll(async ({ browser }) => { + page = await browser.newPage() + }) + + test.afterAll(async () => { + await page.close() + }) + + test('9.0 Shortcut declaration', async () => { + let token = await getToken('j.musonda', 'test') + const declarationInput = { + child: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName(), + gender: 'male' + }, + informant: { + type: 'BROTHER' + }, + attendant: { + type: 'PHYSICIAN' + }, + mother: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + }, + father: { + firstNames: faker.name.firstName(), + familyName: faker.name.firstName() + } + } as ConvertEnumsToStrings + + const res = await createDeclaration(token, declarationInput) + expect(res).toStrictEqual({ + trackingId: expect.any(String), + compositionId: expect.any(String), + isPotentiallyDuplicate: false, + __typename: 'CreatedIds' + }) + + trackingId = res.trackingId + + token = await getToken('j.musonda', 'test') + declaration = (await fetchDeclaration(token, res.compositionId)).data + .fetchBirthRegistration as BirthDeclaration + }) + + test.describe('9.1 Print > Ready to issue', async () => { + test('9.1.1 print', async () => { + await login(page, 'j.musonda', 'test') + await createPIN(page) + + await page.getByPlaceholder('Search for a tracking ID').fill(trackingId) + await page.getByPlaceholder('Search for a tracking ID').press('Enter') + await page.locator('#ListItemAction-0-icon').click() + await page.locator('#name_0').click() + + await page.getByRole('button', { name: 'Print', exact: true }).click() + + await page.getByLabel('Print in advance').check() + await page.getByRole('button', { name: 'Continue' }).click() + await page.getByRole('button', { name: 'Yes, print certificate' }).click() + await page.getByRole('button', { name: 'Print', exact: true }).click() + }) + test('9.1.2 Ready to issue', async () => { + await page.getByRole('button', { name: 'Ready to issue' }).click() + + /* + * Expected result: should + * - be navigated to ready to isssue tab + * - include the declaration in this tab + */ + expect(page.url().includes('registration-home/readyToIssue')).toBeTruthy() + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + }) + test('9.1.3 Record audit', async () => { + await page.getByLabel('Assign record').click() + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show correct record button + */ + + await page + .getByRole('button', { name: 'Correct record', exact: true }) + .click() + }) + }) + + test('9.2 Correction requester: Me', async () => { + await page.getByLabel('Me', { exact: true }).check() + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('9.3 Verify identity', async () => { + /* + * Expected result: + * - should not show verify identity + * - should directly navigate to review page + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('review')).toBeTruthy() + }) + + test.describe('9.4 Correction made on informant details', async () => { + test('9.4.1 Change relationship to child', async () => { + await page + .locator('#informant-content #Relationship') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informantType + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantType')).toBeTruthy() + + await page.locator('#informantType').click() + await page.getByText(updatedInformantDetails.relationship).click() + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous relation with strikethrough + * - show updated relation + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Relationship').getByRole('deletion') + ).toHaveText(declaration.registration.informantType, { ignoreCase: true }) + + await expect( + page + .locator('#informant-content #Relationship') + .getByText(updatedInformantDetails.relationship) + ).toBeVisible() + }) + + test('9.4.2 Change name', async () => { + await page + .locator('#informant-content #Full') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's family name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + // expect(page.url().includes('#familyNameEng')).toBeTruthy() // fail: does not focus on infirmant's family name + + await page + .locator('#firstNamesEng') + .fill(updatedInformantDetails.firstNames) + await page + .locator('#familyNameEng') + .fill(updatedInformantDetails.familyName) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous name with strikethrough + * - show updated name + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + const oldData = await page + .locator('#informant-content #Full') + .getByRole('deletion') + .all() + + await expect(oldData[0]).toHaveText( + declaration.informant.name[0].firstNames + ) + await expect(oldData[1]).toHaveText( + declaration.informant.name[0].familyName + ) + + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.firstNames) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Full') + .getByText(updatedInformantDetails.familyName) + ).toBeVisible() + }) + + test('9.4.3 Change date of birth', async () => { + await page + .locator('#informant-content #Date') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's date of birth + */ + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantBirthDate')).toBeTruthy() + + const birthDay = updatedInformantDetails.birthDate.split('-') + + await page.getByPlaceholder('dd').fill(birthDay[2]) + await page.getByPlaceholder('mm').fill(birthDay[1]) + await page.getByPlaceholder('yyyy').fill(birthDay[0]) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous gender with strikethrough + * - show updated gender + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Date').getByRole('deletion') + ).toHaveText( + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy'), + { ignoreCase: true } + ) + + await expect( + page + .locator('#informant-content #Date') + .getByText( + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + }) + + test('9.4.4 Change nationality', async () => { + await page + .locator('#informant-content #Nationality') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#nationality')).toBeTruthy() + + await page.locator('#nationality').click() + await page.getByText(updatedInformantDetails.nationality).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous nationality with strikethrough + * - show updated nationality + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Nationality').getByRole('deletion') + ).toHaveText('Farajaland', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Nationality') + .getByText(updatedInformantDetails.nationality) + ).toBeVisible() + }) + + test('9.4.5 Change id type', async () => { + await page + .locator('#informant-content #Type') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantIdType')).toBeTruthy() + + await page.locator('#informantIdType').click() + await page.getByText(updatedInformantDetails.idType).click() + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id type with strikethrough + * - show updated id type + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Type').getByRole('deletion') + ).toHaveText('National Id', { + ignoreCase: true + }) + + await expect( + page + .locator('#informant-content #Type') + .getByText(updatedInformantDetails.idType) + ).toBeVisible() + }) + + test('9.4.6 Change id', async () => { + await page + .locator('#informant-content #ID') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#informantPassport')).toBeTruthy() + + await page.locator('#informantPassport').fill(updatedInformantDetails.id) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous id with strikethrough + * - show updated id + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page + .locator('#informant-content #ID') + .getByText(updatedInformantDetails.id) + ).toBeVisible() + }) + + test('9.4.7 Change usual place of residence', async () => { + await page + .locator('#informant-content #Usual') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#countryPrimary')).toBeTruthy() + + await page.locator('#statePrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.province).click() + + await page.locator('#districtPrimaryInformant').click() + await page.getByText(updatedInformantDetails.address.district).click() + + await page + .locator('#cityPrimaryInformant') + .fill(updatedInformantDetails.address.town) + + await page + .locator('#addressLine1UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.residentialArea) + + await page + .locator('#addressLine2UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.street) + + await page + .locator('#addressLine3UrbanOptionPrimaryInformant') + .fill(updatedInformantDetails.address.number) + + await page + .locator('#postalCodePrimaryInformant') + .fill(updatedInformantDetails.address.zipCode) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Usual place of resiedence with strikethrough + * - show updated Usual place of resiedence + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(1) + ).toHaveText('Farajaland', { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(2) + ).toHaveText('Central', { ignoreCase: true }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(3) + ).toHaveText('Ibombo', { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(5) + ).toHaveText(declaration.informant.address[0].city, { ignoreCase: true }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(6) + ).toHaveText(declaration.informant.address[0].line[2], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(7) + ).toHaveText(declaration.informant.address[0].line[1], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(8) + ).toHaveText(declaration.informant.address[0].line[0], { + ignoreCase: true + }) + await expect( + page.locator('#informant-content #Usual').getByRole('deletion').nth(9) + ).toHaveText(declaration.informant.address[0].postalCode, { + ignoreCase: true + }) + + await expect( + page.locator('#informant-content #Usual').getByText('Farajaland') + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.province) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.district) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.town) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.residentialArea) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.street) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.number) + ).toBeVisible() + await expect( + page + .locator('#informant-content #Usual') + .getByText(updatedInformantDetails.address.zipCode) + ).toBeVisible() + }) + + test('9.4.8 Change email', async () => { + await page + .locator('#informant-content #Email') + .getByRole('button', { name: 'Change', exact: true }) + .click() + + /* + * Expected result: should + * - redirect to informant's details page + * - focus on informant's Email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('informant-view-group')).toBeTruthy() + expect(page.url().includes('#registrationEmail')).toBeTruthy() + + await page + .locator('#registrationEmail') + .fill(updatedInformantDetails.email) + + await page.waitForTimeout(500) + + await page.getByRole('button', { name: 'Back to review' }).click() + + /* + * Expected result: should + * - redirect to review page + * - show previous Email with strikethrough + * - show updated Email + */ + + expect(page.url().includes('correction')).toBeTruthy() + expect(page.url().includes('review')).toBeTruthy() + + await expect( + page.locator('#informant-content #Email').getByRole('deletion') + ).toHaveText(declaration.registration.contactEmail, { ignoreCase: true }) + + await expect( + page + .locator('#informant-content #Email') + .getByText(updatedInformantDetails.email) + ).toBeVisible() + }) + }) + + test('9.5 Upload supporting documents', async () => { + await page.getByRole('button', { name: 'Continue' }).click() + + /* + * Expected result: should + * - navigate to supporting document + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('supportingDocuments')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page.getByLabel('No supporting documents required').check() + + /* + * Expected result: should enable the continue button + */ + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('9.6 Reason for correction', async () => { + /* + * Expected result: should + * - navigate to reason for correction + * - continue button is disabled + */ + expect(page.url().includes('correction')).toBeTruthy() + + expect(page.url().includes('reason')).toBeTruthy() + + await expect(page.getByRole('button', { name: 'Continue' })).toBeDisabled() + + await page + .getByLabel('Requested to do so by the court (Judicial order)') + .check() + + await page + .locator('#additionalComment') + .fill(declaration.registration.registrationNumber) + + await page.getByRole('button', { name: 'Continue' }).click() + }) + + test('9.7 Correction summary', async () => { + /* + * Expected result: should + * - navigate to correction summary + * - Make correction button is disabled + */ + expect(page.url().includes('summary')).toBeTruthy() + expect(page.url().includes('correction')).toBeTruthy() + + await expect( + page.getByRole('button', { name: 'Make correction' }) + ).toBeDisabled() + + /* + * Expected result: should show + * - Original vs correction + * - Requested by + * - ID check + * - Reason for request + * - Comments + */ + + await expect( + page.getByText( + 'Relationship to child (Informant)' + + declaration.informant.relationship + + updatedInformantDetails.relationship + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Full name (informant)' + + declaration.informant.name[0].firstNames + + ' ' + + declaration.informant.name[0].familyName + + updatedInformantDetails.firstNames + + ' ' + + updatedInformantDetails.familyName + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Date of birth (informant)' + + format(parseISO(declaration.informant.birthDate), 'dd MMMM yyyy') + + format(parseISO(updatedInformantDetails.birthDate), 'dd MMMM yyyy') + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Nationality (Informant)Farajaland' + + updatedInformantDetails.nationality + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Type of ID (Informant)National ID' + updatedInformantDetails.idType + ) + ).toBeVisible() + await expect( + page.getByText('ID Number (Informant)-' + updatedInformantDetails.id) + ).toBeVisible() + + await expect( + page.getByText( + 'Usual place of residence (Informant)FarajalandCentralIbombo-' + + declaration.informant.address[0].city + + declaration.informant.address[0].line[2] + + declaration.informant.address[0].line[1] + + declaration.informant.address[0].line[0] + + declaration.informant.address[0].postalCode + + 'Farajaland' + + updatedInformantDetails.address.province + + updatedInformantDetails.address.district + + updatedInformantDetails.address.town + + updatedInformantDetails.address.residentialArea + + updatedInformantDetails.address.street + + updatedInformantDetails.address.number + + updatedInformantDetails.address.zipCode + ) + ).toBeVisible() + + await expect( + page.getByText( + 'Email (Informant)' + + declaration.registration.contactEmail + + updatedInformantDetails.email + ) + ).toBeVisible() + + await expect(page.getByText('Me', { exact: true })).toBeVisible() + await expect( + page.getByText('Requested to do so by the court (Judicial order)') + ).toBeVisible() + await expect( + page.getByText(declaration.registration.registrationNumber) + ).toBeVisible() + + await page.getByLabel('No').check() + + /* + * Expected result: should enable the Make correction button + */ + await page.getByRole('button', { name: 'Make correction' }).click() + await page.getByRole('button', { name: 'Confirm' }).click() + + await page.getByRole('button', { name: 'Ready to print' }).click() + + /* + * Expected result: should + * - be navigated to ready to print tab + * - include the declaration in this tab + */ + await expect(page.locator('#navigation_outbox')).not.toContainText('1', { + timeout: 1000 * 30 + }) + + await expect( + page.getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + ).toBeVisible() + }) + test('9.8 Validate history in record audit', async () => { + await page + .getByText( + declaration.child.name[0].firstNames + + ' ' + + declaration.child.name[0].familyName + ) + .click() + + await page.getByLabel('Assign record').click() + if ( + await page + .getByRole('button', { name: 'Assign', exact: true }) + .isVisible() + ) + await page.getByRole('button', { name: 'Assign', exact: true }).click() + + /* + * Expected result: should show in task history + * - Record corrected + */ + + await expect( + page + .locator('#listTable-task-history') + .getByRole('button', { name: 'Record corrected' }) + ).toBeVisible() + }) +}) diff --git a/e2e/testcases/birth/helpers.ts b/e2e/testcases/birth/helpers.ts index e41562188..3b8bccaaf 100644 --- a/e2e/testcases/birth/helpers.ts +++ b/e2e/testcases/birth/helpers.ts @@ -1,30 +1,20 @@ -import gql from 'graphql-tag' -import { print } from 'graphql/language/printer' import { GATEWAY_HOST } from '../../constants' import { BirthRegistrationInput } from '../../gateway' import faker from '@faker-js/faker' -import type testData from './data/1-both-mother-and-father.json' import { readFileSync } from 'fs' import uuid from 'uuid' import { format, subDays, subYears } from 'date-fns' -import { Bundle } from 'typescript' import { join } from 'path' - -export const CREATE_BIRTH_REGISTRATION = print(gql` - mutation createBirthRegistration($details: BirthRegistrationInput!) { - createBirthRegistration(details: $details) { - trackingId - compositionId - isPotentiallyDuplicate - __typename - } - } -`) +import { + CREATE_BIRTH_REGISTRATION, + GET_BIRTH_REGISTRATION_FOR_REVIEW, + REGISTER_BIRTH_DECLARATION +} from './queries' type Details = { informant: { - type: 'MOTHER' | 'FATHER' + type: 'MOTHER' | 'FATHER' | 'BROTHER' } child: { firstNames: string @@ -94,7 +84,7 @@ export async function createDeclaration(token: string, details: Details) { join(__dirname, './data/assets/528KB-random.png') ).toString('base64'), informantType: details.informant.type, - contactPhoneNumber: '+260' + faker.random.numeric(9), + contactPhoneNumber: '0' + faker.random.numeric(9), contactEmail: faker.internet.email(), draftId: uuid.v4() }, @@ -184,6 +174,10 @@ export async function createDeclaration(token: string, details: Details) { { fieldId: 'birth.father.father-view-group.fatherIdType', value: 'NATIONAL_ID' + }, + { + fieldId: 'birth.informant.informant-view-group.informantIdType', + value: 'NATIONAL_ID' } ], father: { @@ -238,6 +232,54 @@ export async function createDeclaration(token: string, details: Details) { ], maritalStatus: 'SINGLE', educationalAttainment: 'NO_SCHOOLING' + }, + informant: { + name: [ + { + use: 'en', + firstNames: faker.name.findName(), + familyName: faker.name.lastName() + } + ], + birthDate: format( + subYears(new Date(), 16 + Math.ceil(10 * Math.random())), + 'yyyy-MM-dd' + ), + nationality: ['FAR'], + identifier: [ + { + id: faker.random.numeric(10), + type: 'NATIONAL_ID' + } + ], + address: [ + { + type: 'PRIMARY_ADDRESS', + line: [ + '343', + 'Example Street', + 'Example Residential Area', + '', + '', + 'URBAN', + '', + '', + '', + '', + '', + '', + '', + '', + '' + ], + country: 'FAR', + state: getLocationIdByName(locations, 'Central'), + partOf: getLocationIdByName(locations, 'Ibombo'), + district: getLocationIdByName(locations, 'Ibombo'), + city: 'Example Town', + postalCode: '534534' + } + ] } } satisfies ConvertEnumsToStrings } @@ -246,7 +288,53 @@ export async function createDeclaration(token: string, details: Details) { return res.json().then((r) => r.data.createBirthRegistration) } -type ConvertEnumsToStrings = T extends (infer U)[] +export const fetchDeclaration = async ( + token: string, + compositionId: string +) => { + const res = await fetch(`${GATEWAY_HOST}/graphql`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + query: GET_BIRTH_REGISTRATION_FOR_REVIEW, + variables: { + id: compositionId + } + }) + }) + return await res.json() +} + +export const registerDeclaration = async ( + token: string, + compositionId: string +) => { + await fetchDeclaration(token, compositionId) + const res = await fetch(`${GATEWAY_HOST}/graphql`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + query: REGISTER_BIRTH_DECLARATION, + variables: { + id: compositionId, + details: { + createdAt: new Date().toISOString() + } satisfies ConvertEnumsToStrings + } + }) + }) + const t = await res.json() + + return await t +} + +export type ConvertEnumsToStrings = T extends (infer U)[] ? ConvertEnumsToStrings[] : T extends string ? `${T}` diff --git a/e2e/testcases/birth/queries.ts b/e2e/testcases/birth/queries.ts new file mode 100644 index 000000000..ec7c183bb --- /dev/null +++ b/e2e/testcases/birth/queries.ts @@ -0,0 +1,325 @@ +import gql from 'graphql-tag' +import { print } from 'graphql/language/printer' + +export const CREATE_BIRTH_REGISTRATION = print(gql` + mutation createBirthRegistration($details: BirthRegistrationInput!) { + createBirthRegistration(details: $details) { + trackingId + compositionId + isPotentiallyDuplicate + __typename + } + } +`) + +export const GET_BIRTH_REGISTRATION_FOR_REVIEW = print(gql` + query fetchBirthRegistrationForReview($id: ID!) { + fetchBirthRegistration(id: $id) { + _fhirIDMap + id + child { + id + identifier { + id + type + otherType + } + name { + use + firstNames + middleName + familyName + } + birthDate + gender + } + informant { + id + relationship + otherRelationship + _fhirIDPatient + identifier { + id + type + otherType + fieldsModifiedByIdentity + } + name { + use + firstNames + middleName + familyName + } + occupation + nationality + birthDate + ageOfIndividualInYears + exactDateOfBirthUnknown + address { + type + line + district + state + city + postalCode + country + } + } + mother { + id + name { + use + firstNames + middleName + familyName + } + multipleBirth + birthDate + maritalStatus + occupation + detailsExist + reasonNotApplying + ageOfIndividualInYears + exactDateOfBirthUnknown + dateOfMarriage + educationalAttainment + nationality + identifier { + id + type + otherType + fieldsModifiedByIdentity + } + address { + type + line + district + state + city + postalCode + country + } + telecom { + system + value + } + } + father { + id + name { + use + firstNames + middleName + familyName + } + birthDate + maritalStatus + occupation + detailsExist + reasonNotApplying + ageOfIndividualInYears + exactDateOfBirthUnknown + dateOfMarriage + educationalAttainment + nationality + identifier { + id + type + otherType + fieldsModifiedByIdentity + } + address { + type + line + district + state + city + postalCode + country + } + telecom { + system + value + } + } + registration { + id + informantType + otherInformantType + contact + contactRelationship + contactPhoneNumber + contactEmail + duplicates { + compositionId + trackingId + } + informantsSignature + attachments { + data + uri + type + contentType + subject + } + status { + comments { + comment + } + type + timestamp + office { + name + alias + address { + district + state + } + partOf + } + } + type + trackingId + registrationNumber + mosipAid + } + attendantAtBirth + weightAtBirth + birthType + eventLocation { + id + type + address { + line + district + state + city + postalCode + country + } + } + questionnaire { + fieldId + value + } + history { + otherReason + requester + requesterOther + noSupportingDocumentationRequired + hasShowedVerifiedDocument + date + action + regStatus + dhis2Notification + ipAddress + documents { + id + data + uri + type + } + payment { + id + type + amount + outcome + date + attachmentURL + } + statusReason { + text + } + reason + location { + id + name + } + office { + id + name + alias + address { + state + district + } + } + system { + name + type + } + user { + id + role { + _id + labels { + lang + label + } + } + systemRole + name { + firstNames + familyName + use + } + avatar { + data + type + } + } + signature { + data + type + } + comments { + user { + id + username + avatar { + data + type + } + } + comment + createdAt + } + input { + valueCode + valueId + value + } + output { + valueCode + valueId + value + } + certificates { + hasShowedVerifiedDocument + collector { + relationship + otherRelationship + name { + use + firstNames + familyName + } + telecom { + system + value + use + } + } + } + duplicateOf + potentialDuplicates + } + } + } +`) + +export const REGISTER_BIRTH_DECLARATION = print(gql` + mutation markBirthAsRegistered($id: ID!, $details: BirthRegistrationInput!) { + markBirthAsRegistered(id: $id, details: $details) + } +`) diff --git a/e2e/testcases/birth/types.ts b/e2e/testcases/birth/types.ts new file mode 100644 index 000000000..d14e56584 --- /dev/null +++ b/e2e/testcases/birth/types.ts @@ -0,0 +1,252 @@ +export type BirthInputDetails = { + informant: { + type: 'MOTHER' | 'FATHER' | 'BROTHER' + } + child: { + firstNames: string + familyName: string + birthDate?: string + gender: 'male' | 'female' + birthType?: 'SINGLE' | 'MULTIPLE' + weightAtBirth?: number + } + mother: { + firstNames: string + familyName: string + birthDate?: string + maritalStatus?: 'SINGLE' | 'MARRIED' | 'DIVORCED' | 'WIDOWED' + } + father: { + firstNames: string + familyName: string + birthDate?: string + } + attendant: { + type: 'PHYSICIAN' | 'NURSE' | 'MIDWIFE' | 'OTHER' + } +} + +export type BirthDeclaration = { + _fhirIDMap: { + composition: string + encounter: string + eventLocation: string + observation: { + birthType: string + weightAtBirth: string + attendantAtBirth: string + } + questionnaireResponse: string + } + id: string + child: { + id: string + identifier: { + id: string + type: string + otherType: string | null + }[] + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + birthDate: string + gender: string + } + informant: { + id: string + relationship: string + otherRelationship: string | null + _fhirIDPatient: string + identifier: { + id: string + type: string + otherType: string | null + fieldsModifiedByIdentity: string | null + }[] + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + occupation: string | null + nationality: string[] + birthDate: string + ageOfIndividualInYears: number | null + exactDateOfBirthUnknown: boolean | null + address: { + type: string + line: string[] + district: string + state: string + city: string + postalCode: string + country: string + }[] + } + mother: { + id: string + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + multipleBirth: boolean | null + birthDate: string + maritalStatus: string + occupation: string | null + detailsExist: boolean + reasonNotApplying: string | null + ageOfIndividualInYears: number | null + exactDateOfBirthUnknown: boolean | null + dateOfMarriage: string | null + educationalAttainment: string + nationality: string[] + identifier: { + id: string + type: string + otherType: string | null + fieldsModifiedByIdentity: string | null + }[] + address: { + type: string + line: string[] + district: string + state: string + city: string + postalCode: string + country: string + }[] + telecom: string | null + } + father: { + id: string + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + birthDate: string + maritalStatus: string + occupation: string | null + detailsExist: boolean + reasonNotApplying: string | null + ageOfIndividualInYears: number | null + exactDateOfBirthUnknown: boolean | null + dateOfMarriage: string | null + educationalAttainment: string + nationality: string[] + identifier: { + id: string + type: string + otherType: string | null + fieldsModifiedByIdentity: string | null + }[] + address: { + type: string + line: string[] + district: string + state: string + city: string + postalCode: string + country: string + }[] + telecom: string | null + } + registration: { + id: string + informantType: string + otherInformantType: string | null + contact: string | null + contactRelationship: string | null + contactPhoneNumber: string + contactEmail: string + duplicates: string | null + informantsSignature: string + informantsSignatureURI: string + attachments: string | null + status: { + comments: string | null + type: string + timestamp: string + office: { + name: string + alias: string[] + address: string | null + partOf: string + } + }[] + type: string + trackingId: string + registrationNumber: string + mosipAid: string | null + } + attendantAtBirth: string + weightAtBirth: number + birthType: string + eventLocation: { + id: string + type: string + address: string | null + } + questionnaire: { + fieldId: string + value: string + }[] + history: { + otherReason: string + requester: string + requesterOther: string + noSupportingDocumentationRequired: boolean + hasShowedVerifiedDocument: boolean + date: string + action: string | null + regStatus: string + dhis2Notification: boolean + ipAddress: string | null + documents: string[] + payment: string | null + statusReason: string | null + reason: string | null + location: { + id: string + name: string + } + office: { + id: string + name: string + alias: string[] + address: string | null + } + system: string | null + user: { + id: string + role: { + _id: string + labels: { + lang: string + label: string + }[] + } + systemRole: string + name: { + firstNames: string + familyName: string + use: string + }[] + avatar: string | null + } + signature: string | null + comments: string[] + input: string[] + output: string[] + certificates: string[] + duplicateOf: string | null + potentialDuplicates: string | null + }[] +} diff --git a/e2e/testcases/death/helpers.ts b/e2e/testcases/death/helpers.ts index 5f5d4cf90..79e8f69f1 100644 --- a/e2e/testcases/death/helpers.ts +++ b/e2e/testcases/death/helpers.ts @@ -1,5 +1,3 @@ -import gql from 'graphql-tag' -import { print } from 'graphql/language/printer' import { GATEWAY_HOST } from '../../constants' import { DeathRegistrationInput } from '../../gateway' import faker from '@faker-js/faker' @@ -9,17 +7,10 @@ import uuid from 'uuid' import { format } from 'date-fns' import { join } from 'path' import { getRandomDate } from '../../helpers' - -export const CREATE_DEATH_REGISTRATION = print(gql` - mutation createDeathRegistration($details: DeathRegistrationInput!) { - createDeathRegistration(details: $details) { - trackingId - compositionId - isPotentiallyDuplicate - __typename - } - } -`) +import { + CREATE_DEATH_REGISTRATION, + GET_DEATH_REGISTRATION_FOR_REVIEW +} from './queries' const declaration = { deceased: { @@ -281,6 +272,27 @@ export async function createDeathDeclaration(token: string) { return res.json().then((r) => r.data.createDeathRegistration) } +export const fetchDeclaration = async ( + token: string, + compositionId: string +) => { + const res = await fetch(`${GATEWAY_HOST}/graphql`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + query: GET_DEATH_REGISTRATION_FOR_REVIEW, + variables: { + id: compositionId + } + }) + }) + + return await res.json() +} + type ConvertEnumsToStrings = T extends (infer U)[] ? ConvertEnumsToStrings[] : T extends string diff --git a/e2e/testcases/death/queries.ts b/e2e/testcases/death/queries.ts new file mode 100644 index 000000000..52eb3734b --- /dev/null +++ b/e2e/testcases/death/queries.ts @@ -0,0 +1,386 @@ +import gql from 'graphql-tag' +import { print } from 'graphql/language/printer' + +export const CREATE_DEATH_REGISTRATION = print(gql` + mutation createDeathRegistration($details: DeathRegistrationInput!) { + createDeathRegistration(details: $details) { + trackingId + compositionId + isPotentiallyDuplicate + __typename + } + } +`) + +export const GET_DEATH_REGISTRATION_FOR_REVIEW = print(gql` + query fetchDeathRegistrationForReview($id: ID!) { + fetchDeathRegistration(id: $id) { + _fhirIDMap + id + deceased { + id + name { + use + firstNames + middleName + familyName + } + birthDate + age + ageOfIndividualInYears + exactDateOfBirthUnknown + gender + maritalStatus + occupation + nationality + identifier { + id + type + otherType + } + gender + deceased { + deathDate + } + address { + type + line + district + state + city + postalCode + country + } + } + informant { + id + relationship + otherRelationship + _fhirIDPatient + identifier { + id + type + otherType + } + name { + use + firstNames + middleName + familyName + } + nationality + occupation + birthDate + ageOfIndividualInYears + exactDateOfBirthUnknown + telecom { + system + value + } + address { + type + line + district + state + city + postalCode + country + } + } + father { + id + name { + use + firstNames + middleName + familyName + } + birthDate + maritalStatus + occupation + detailsExist + reasonNotApplying + ageOfIndividualInYears + exactDateOfBirthUnknown + dateOfMarriage + educationalAttainment + nationality + identifier { + id + type + otherType + fieldsModifiedByIdentity + } + address { + type + line + district + state + city + postalCode + country + } + telecom { + system + value + } + } + mother { + id + name { + use + firstNames + middleName + familyName + } + birthDate + maritalStatus + occupation + detailsExist + reasonNotApplying + ageOfIndividualInYears + exactDateOfBirthUnknown + dateOfMarriage + educationalAttainment + nationality + identifier { + id + type + otherType + fieldsModifiedByIdentity + } + address { + type + line + district + state + city + postalCode + country + } + telecom { + system + value + } + } + spouse { + id + name { + use + firstNames + middleName + familyName + } + birthDate + maritalStatus + occupation + detailsExist + reasonNotApplying + ageOfIndividualInYears + exactDateOfBirthUnknown + dateOfMarriage + educationalAttainment + nationality + identifier { + id + type + otherType + fieldsModifiedByIdentity + } + address { + type + line + district + state + city + postalCode + country + } + telecom { + system + value + } + } + medicalPractitioner { + name + qualification + lastVisitDate + } + registration { + id + contact + informantType + otherInformantType + contactRelationship + contactPhoneNumber + contactEmail + duplicates { + compositionId + trackingId + } + informantsSignature + attachments { + data + uri + type + contentType + subject + } + status { + comments { + comment + } + type + timestamp + office { + name + alias + address { + district + state + } + partOf + } + } + type + trackingId + registrationNumber + } + eventLocation { + id + type + address { + type + line + district + state + city + postalCode + country + } + } + questionnaire { + fieldId + value + } + mannerOfDeath + causeOfDeathEstablished + causeOfDeathMethod + causeOfDeath + deathDescription + maleDependentsOfDeceased + femaleDependentsOfDeceased + history { + documents { + id + data + uri + type + } + payment { + id + type + amount + outcome + date + attachmentURL + } + otherReason + requester + hasShowedVerifiedDocument + noSupportingDocumentationRequired + date + action + regStatus + dhis2Notification + ipAddress + statusReason { + text + } + reason + location { + id + name + } + office { + id + name + alias + address { + state + district + } + } + system { + name + type + } + user { + id + role { + _id + labels { + lang + label + } + } + systemRole + name { + firstNames + familyName + use + } + avatar { + data + type + } + } + signature { + data + type + } + comments { + user { + id + username + avatar { + data + type + } + } + comment + createdAt + } + input { + valueCode + valueId + value + } + output { + valueCode + valueId + value + } + certificates { + hasShowedVerifiedDocument + collector { + relationship + otherRelationship + name { + use + firstNames + familyName + } + telecom { + system + value + use + } + } + } + duplicateOf + potentialDuplicates + } + } + } +`) diff --git a/e2e/testcases/death/types.ts b/e2e/testcases/death/types.ts new file mode 100644 index 000000000..0f765949c --- /dev/null +++ b/e2e/testcases/death/types.ts @@ -0,0 +1,175 @@ +export type DeathDeclaration = { + _fhirIDMap: { + composition: string + encounter: string + eventLocation: string + observation: { + causeOfDeathEstablished: string + causeOfDeath: string + } + questionnaireResponse: string + } + id: string + deceased: { + id: string + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + birthDate: string + age: any | null + ageOfIndividualInYears: any | null + exactDateOfBirthUnknown: any | null + gender: string + maritalStatus: any | null + occupation: any | null + nationality: string[] + identifier: { id: string; type: string; otherType: any | null }[] + deceased: { deathDate: string } + address: { + type: string + line: string[] + district: string + state: string + city: string + postalCode: string + country: string + }[] + } + informant: { + id: string + relationship: string + otherRelationship: any | null + _fhirIDPatient: string + identifier: { id: string; type: string; otherType: any | null }[] + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + nationality: string[] + occupation: any | null + birthDate: string + ageOfIndividualInYears: any | null + exactDateOfBirthUnknown: any | null + telecom: any | null + address: { + type: string + line: string[] + district: string + state: string + city: string + postalCode: string + country: string + }[] + } + father: any | null + mother: any | null + spouse: { + id: string + name: { + use: string + firstNames: string + middleName: string + familyName: string + }[] + birthDate: string + maritalStatus: any | null + occupation: any | null + detailsExist: boolean + reasonNotApplying: any | null + ageOfIndividualInYears: any | null + exactDateOfBirthUnknown: any | null + dateOfMarriage: any | null + educationalAttainment: any | null + nationality: string[] + identifier: { + id: string + type: string + otherType: any | null + fieldsModifiedByIdentity: any | null + }[] + address: { + type: string + line: string[] + district: string + state: string + city: string + postalCode: string + country: string + }[] + telecom: any | null + } + medicalPractitioner: any | null + registration: { + id: string + contact: any | null + informantType: string + otherInformantType: any | null + contactRelationship: any | null + contactPhoneNumber: any | null + contactEmail: string + duplicates: any | null + informantsSignature: string + informantsSignatureURI: string + attachments: any | null + status: { + comments: any | null + type: string + timestamp: string + office: { + name: string + alias: string[] + address: any | null + partOf: string + } + }[] + type: string + trackingId: string + registrationNumber: string + } + eventLocation: { id: string; type: string; address: any | null } + questionnaire: { fieldId: string; value: string }[] + mannerOfDeath: any | null + causeOfDeathEstablished: string + causeOfDeathMethod: any | null + causeOfDeath: string + deathDescription: any | null + maleDependentsOfDeceased: any | null + femaleDependentsOfDeceased: any | null + history: { + documents: any[] + payment: any | null + otherReason: string + requester: string + hasShowedVerifiedDocument: boolean + noSupportingDocumentationRequired: boolean + date: string + action: string | null + regStatus: string + dhis2Notification: boolean + ipAddress: any | null + statusReason: any | null + reason: any | null + location: { id: string; name: string } + office: { id: string; name: string; alias: string[]; address: any | null } + system: any | null + user: { + id: string + role: { _id: string; labels: { lang: string; label: string }[] } + systemRole: string + name: { firstNames: string; familyName: string; use: string }[] + avatar: any | null + } + signature: any | null + comments: any[] + input: any[] + output: any[] + certificates: any[] + duplicateOf: any | null + potentialDuplicates: any | null + }[] +}