Skip to content

CCM-16489: Add letter authoring e2e tests#930

Open
andykay-nhs wants to merge 6 commits intomainfrom
feature/CCM-16489
Open

CCM-16489: Add letter authoring e2e tests#930
andykay-nhs wants to merge 6 commits intomainfrom
feature/CCM-16489

Conversation

@andykay-nhs
Copy link
Copy Markdown
Contributor

@andykay-nhs andykay-nhs commented Apr 30, 2026

Description

for each letter type

  • create a new template of the letter type
  • upload standard docx. (Im unsure if the template type matters here? the rendered output isn't checked. I did create a spanish translated copy of the standard template but if we're not actually validating the final rendered content then I'm not sure this matters and just the standard one works?)
  • validates persisted template data is expected by querying dynamo via templateStorageHelper. (Saw this in the existing pdf-letter e2e tests)
  • edit template name
  • edit template campaign
  • set printing and postage. (Do we need further e2e tests for different printing and postage types? or is setting the same one okay for this?)
  • fill out short and long form preview inputs and update preview
  • approve
  • confirm approved status of template in template list view
  • validate approved template cannot be edited

One test covers off invalid template scenario (missing address).

Added arabic and large print letters.

Tests succeeding locally:
image

Context

Type of changes

  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would change existing functionality)
  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I am familiar with the contributing guidelines
  • I have followed the code style of the project
  • I have added tests to cover my changes
  • I have updated the documentation accordingly
  • This PR is a result of pair or mob programming

Sensitive Information Declaration

To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including PII (Personal Identifiable Information) / PID (Personal Identifiable Data) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter.

  • I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.

Description

Raising draft to check CI pipeline status

for each letter type

  • create a new template of the letter type
  • upload standard docx. (Im unsure if the template type matters here? the rendered output isn't checked. I did create a spanish translated copy of the standard template but if we're not actually validating the final rendered content then I'm not sure this matters and just the standard one works?)
  • validates persisted template data is expected by querying dynamo via templateStorageHelper. (Saw this in the existing pdf-letter e2e tests)
  • set printing and postage. (Do we need further e2e tests for different printing and postage types? or is setting the same one okay for this?)
  • fill out short and long form preview inputs and update preview
  • approve
  • confirm approved status of template in template list view

Context

Type of changes

  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would change existing functionality)
  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I am familiar with the contributing guidelines
  • I have followed the code style of the project
  • I have added tests to cover my changes
  • I have updated the documentation accordingly
  • This PR is a result of pair or mob programming

Sensitive Information Declaration

To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including PII (Personal Identifiable Information) / PID (Personal Identifiable Data) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter.

  • I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.

@andykay-nhs andykay-nhs force-pushed the feature/CCM-16489 branch 3 times, most recently from bcfb235 to 5de6a57 Compare May 1, 2026 09:26
@andykay-nhs andykay-nhs force-pushed the feature/CCM-16489 branch from 5cb1262 to 5a8a9d4 Compare May 1, 2026 13:34
@andykay-nhs andykay-nhs force-pushed the feature/CCM-16489 branch from 5a8a9d4 to aa1ec8e Compare May 1, 2026 13:35
@andykay-nhs andykay-nhs marked this pull request as ready for review May 1, 2026 13:36
@andykay-nhs andykay-nhs requested a review from a team as a code owner May 1, 2026 13:36
});
}

// Method not intended for use
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could this be made to work as an abstract method?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i had no idea there even was an abstract keyword in typescript! will give this a go

await chooseTemplateTypePage.clickContinueButton();

await expect(page).toHaveURL(
TemplateMgmtBasePage.appUrlSegment + uploadPage.pathTemplate
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

uploadPage.getUrl()?


await expect(async () => {
const template = await templateStorageHelper.getTemplate(key);
expect(template.campaignId).toEqual(campaignId);
Copy link
Copy Markdown
Contributor

@alexnuttall alexnuttall May 1, 2026

Choose a reason for hiding this comment

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

I wonder if it's better to use toMatchObject or similar, instead of individual assertions, because then if an assertion fails, you get the whole object printed out, which can be more useful than just the single property

const choosePrintingAndPostagePage =
new TemplateMgmtChoosePrintingAndPostagePage(page);
const letterVariants =
await context.letterVariants.getGlobalLetterVariants();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What did you think to the idea of using client or campaign specific, rather than global letter variants in some of these tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I thought that because it was covered off in depth else where then it wouldn't really add much value to this but I suppose it could be another parameter to add in to the tests so each letter type is tested with a different variant

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's fine, I don't disagree, just wondered

await shortTab.clickUpdatePreview();

await expect(async () => {
const template = await templateStorageHelper.getTemplate(templateKey);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The backend rendering test is already doing this kind of assertion on personalisationParameters, status, etc. I think it might be better to depend more on UI assertions here.

also would be good to show that the iframe URL has been updated since viewing the intial (unpersonalised) render

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah totally agree, think I copied this over from the existing pdf letter e2e tests but in hindsight it should really only be making assertions based on whats in the UI

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess there's not much you can get from the UI, though, so there's a case for leaving this in

}, 'Persisted long form render is updated with correct personalisation details').toPass(
{ timeout: 40_000 }
);
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe flip between the tabs and assert on the changing iframe URL, and the personalisation fields?

TemplateMgmtReviewAndApproveLetterTemplatePage.urlRegexp
);

await expect(reviewAndApprovePage.shortRenderIFrame).toBeAttached();
Copy link
Copy Markdown
Contributor

@alexnuttall alexnuttall May 1, 2026

Choose a reason for hiding this comment

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

the iframe URLs should match those of the personalised renders from earlier


await test.step('Template is listed and approved', async () => {
await expect(page).toHaveURL(
`/templates${TemplateMgmtMessageTemplatesPage.pathTemplate}`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

new TemplateMgmtMessageTemplatesPage(page).getUrl()?

expect(templateStatus).toEqual('Approved');
});

await test.step('Approved template cannot be edited', async () => {
Copy link
Copy Markdown
Contributor

@alexnuttall alexnuttall May 1, 2026

Choose a reason for hiding this comment

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

it can be deleted, so that could be added as a final step

await chooseTemplateTypePage.getLetterTypeRadio('x0').click();
await chooseTemplateTypePage.clickContinueButton();

await expect(page).toHaveURL(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

as elsewhere, can you use getUrl?

expect(template.files?.docxTemplate?.virusScanStatus).toEqual(
'PASSED'
);
expect(template.templateStatus).toEqual('PENDING_VALIDATION');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you're going to assert on the (transitory) PENDING_VALIDATION, you might as well assert on the spinner being visible too


await expect(async () => {
const template = await templateStorageHelper.getTemplate(key);
expect(template.campaignId).toEqual(campaignId);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

as above, consider using toMatchObject, and whether all these details need to be checked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants