Skip to content

Commit 3dd35a1

Browse files
committed
CCM-7079: NHS App Review page page automation
1 parent 113a5cc commit 3dd35a1

File tree

3 files changed

+381
-1
lines changed

3 files changed

+381
-1
lines changed

src/components/forms/CreateNhsAppTemplate/CreateNhsAppTemplate.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export const CreateNhsAppTemplate: FC<PageComponentProps> = ({
101101
error={templateMessageError}
102102
errorProps={{ id: 'nhsAppTemplateMessage-error-message' }}
103103
/>
104-
<p style={useJsEnabledStyle()}>
104+
<p style={useJsEnabledStyle()} id='character-count'>
105105
{nhsAppTemplateMessage.length}
106106
{characterCountText}
107107
</p>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Locator, Page } from '@playwright/test';
2+
import { TemplateMgmtBasePage } from '../template-mgmt-base-page';
3+
import { TemplateMgmtMessageFormatting } from '../template-mgmt-message-formatting';
4+
5+
export class TemplateMgmtCreateNhsAppPage extends TemplateMgmtBasePage {
6+
public readonly nameInput: Locator;
7+
8+
public readonly messageTextArea: Locator;
9+
10+
public readonly errorSummary: Locator;
11+
12+
public readonly personalisationFields: Locator;
13+
14+
public readonly namingYourTemplate: Locator;
15+
16+
public readonly characterCountText: Locator;
17+
18+
public readonly messageFormatting: TemplateMgmtMessageFormatting;
19+
20+
constructor(page: Page) {
21+
super(page);
22+
this.nameInput = page.locator('[id="nhsAppTemplateName"]');
23+
this.messageTextArea = page.locator('[id="nhsAppTemplateMessage"]');
24+
this.errorSummary = page.locator('[class="nhsuk-error-summary"]');
25+
this.personalisationFields = page.locator(
26+
'[data-testid="personalisation-details"]'
27+
);
28+
this.namingYourTemplate = page.locator(
29+
'[data-testid="how-to-name-your-template"]'
30+
);
31+
this.characterCountText = page.locator('[id="character-count"]');
32+
this.messageFormatting = new TemplateMgmtMessageFormatting(page);
33+
}
34+
35+
async loadPage(sessionId: string) {
36+
await this.navigateTo(`/templates/create-nhs-app-template/${sessionId}`);
37+
}
38+
}
Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
import { test, expect } from '@playwright/test';
2+
import SessionStorageHelper from '../../helpers/session-storage-helper';
3+
import { TemplateMgmtCreateNhsAppPage } from '../../pages/nhs-app/template-mgmt-create-nhs-app-page';
4+
import { SessionFactory } from '../../helpers/session-factory';
5+
import {
6+
assertFooterLinks,
7+
assertGoBackLink,
8+
assertLoginLink,
9+
assertNotifyBannerLink,
10+
assertSkipToMainContent,
11+
} from '../template-mgmt-common.steps';
12+
13+
const sessions = {
14+
empty: SessionFactory.createNhsAppSession('empty-nhs-app-session'),
15+
submit: SessionFactory.createNhsAppSession('submit-nhs-app-session'),
16+
submitAndReturn: SessionFactory.createNhsAppSession(
17+
'submit-and-return-create-nhs-app-session'
18+
),
19+
goBackAndReturn: SessionFactory.createNhsAppSession(
20+
'go-back-nhs-app-session'
21+
),
22+
noNhsAppTemplateType: SessionFactory.create({
23+
id: 'no-nhs-app-template-type-session',
24+
templateType: 'UNKNOWN',
25+
}),
26+
previousData: {
27+
...SessionFactory.createNhsAppSession('previous-data-nhs-app-session'),
28+
nhsAppTemplateName: 'previous-data-nhs-app-template',
29+
nhsAppTemplateMessage: 'previous-data-nhs-app-template-message',
30+
},
31+
};
32+
33+
test.describe('Create NHS App template Page', () => {
34+
const sessionStorageHelper = new SessionStorageHelper(
35+
Object.values(sessions)
36+
);
37+
38+
test.beforeAll(async () => {
39+
await sessionStorageHelper.seedSessionData();
40+
});
41+
42+
test.afterAll(async () => {
43+
await sessionStorageHelper.deleteSessionData();
44+
});
45+
46+
test('when user visits page, then page is loaded', async ({
47+
page,
48+
baseURL,
49+
}) => {
50+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
51+
52+
await createNhsAppTemplatePage.loadPage(sessions.empty.id);
53+
54+
await expect(page).toHaveURL(
55+
`${baseURL}/templates/create-nhs-app-template/${sessions.empty.id}`
56+
);
57+
58+
expect(await createNhsAppTemplatePage.pageHeader.textContent()).toBe(
59+
'Create NHS App message template'
60+
);
61+
});
62+
63+
test.describe('Page functionality', () => {
64+
test('common page tests', async ({ page, baseURL }) => {
65+
const props = {
66+
page: new TemplateMgmtCreateNhsAppPage(page),
67+
id: sessions.empty.id,
68+
baseURL,
69+
};
70+
71+
await assertSkipToMainContent(props);
72+
await assertNotifyBannerLink(props);
73+
await assertLoginLink(props);
74+
await assertFooterLinks(props);
75+
await assertGoBackLink({
76+
...props,
77+
expectedUrl: `templates/choose-a-template-type/${sessions.empty.id}`,
78+
});
79+
});
80+
81+
test('when user visits page with previous data, then form fields retain previous data', async ({
82+
page,
83+
}) => {
84+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
85+
86+
await createNhsAppTemplatePage.loadPage(sessions.previousData.id);
87+
88+
await expect(createNhsAppTemplatePage.nameInput).toHaveValue(
89+
sessions.previousData.nhsAppTemplateName
90+
);
91+
await expect(createNhsAppTemplatePage.messageTextArea).toHaveValue(
92+
sessions.previousData.nhsAppTemplateMessage
93+
);
94+
});
95+
96+
test('character count', async ({ page }) => {
97+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
98+
99+
await createNhsAppTemplatePage.loadPage(sessions.submit.id);
100+
101+
await createNhsAppTemplatePage.nameInput.fill('template-name');
102+
103+
await createNhsAppTemplatePage.messageTextArea.fill('a'.repeat(100));
104+
105+
await expect(createNhsAppTemplatePage.characterCountText).toHaveText(
106+
'100 of 5000 characters'
107+
);
108+
109+
await createNhsAppTemplatePage.messageTextArea.fill('a'.repeat(1000));
110+
111+
await expect(createNhsAppTemplatePage.characterCountText).toHaveText(
112+
'1000 of 5000 characters'
113+
);
114+
});
115+
116+
test('when user clicks "Go back" and returns, then form fields retain previous data', async ({
117+
baseURL,
118+
page,
119+
}) => {
120+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
121+
122+
await createNhsAppTemplatePage.loadPage(sessions.goBackAndReturn.id);
123+
124+
await createNhsAppTemplatePage.nameInput.fill(
125+
'This is an NHS App template name'
126+
);
127+
128+
await createNhsAppTemplatePage.messageTextArea.fill(
129+
'This is an NHS App message'
130+
);
131+
132+
await createNhsAppTemplatePage.goBackLink.click();
133+
134+
await expect(page).toHaveURL(
135+
`${baseURL}/templates/choose-a-template-type/${sessions.goBackAndReturn.id}`
136+
);
137+
138+
await page.getByRole('button', { name: 'Continue' }).click();
139+
140+
await expect(createNhsAppTemplatePage.nameInput).toHaveValue(
141+
'This is an NHS App template name'
142+
);
143+
144+
await expect(createNhsAppTemplatePage.messageTextArea).toHaveValue(
145+
'This is an NHS App message'
146+
);
147+
});
148+
149+
test('when user clicks "Personalisation" tool tips, then tool tips are displayed', async ({
150+
page,
151+
}) => {
152+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
153+
154+
await createNhsAppTemplatePage.loadPage(sessions.goBackAndReturn.id);
155+
156+
await createNhsAppTemplatePage.personalisationFields.click();
157+
158+
await expect(
159+
createNhsAppTemplatePage.personalisationFields
160+
).toHaveAttribute('open');
161+
});
162+
163+
test('when user clicks "Message formatting" tool tips, then tool tips are displayed', async ({
164+
page,
165+
}) => {
166+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
167+
168+
await createNhsAppTemplatePage.loadPage(sessions.empty.id);
169+
170+
await createNhsAppTemplatePage.messageFormatting.assertDetailsOpen([
171+
createNhsAppTemplatePage.messageFormatting.linksAndUrls,
172+
]);
173+
});
174+
175+
test('when user clicks "Naming your templates" tool tips, then tool tips are displayed', async ({
176+
page,
177+
}) => {
178+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
179+
180+
await createNhsAppTemplatePage.loadPage(sessions.empty.id);
181+
182+
await createNhsAppTemplatePage.namingYourTemplate.click({
183+
position: { x: 0, y: 0 },
184+
});
185+
186+
await expect(createNhsAppTemplatePage.namingYourTemplate).toHaveAttribute(
187+
'open'
188+
);
189+
});
190+
191+
test('when user submits form with valid data, then the next page is displayed', async ({
192+
baseURL,
193+
page,
194+
}) => {
195+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
196+
197+
await createNhsAppTemplatePage.loadPage(sessions.submit.id);
198+
199+
await createNhsAppTemplatePage.nameInput.fill(
200+
'This is an NHS App template name'
201+
);
202+
203+
await createNhsAppTemplatePage.messageTextArea.fill(
204+
'This is an NHS App message'
205+
);
206+
207+
await createNhsAppTemplatePage.clickContinueButton();
208+
209+
await expect(page).toHaveURL(
210+
`${baseURL}/templates/preview-nhs-app-template/${sessions.submit.id}`
211+
);
212+
});
213+
214+
test('when user submits form with valid data and returns, then form fields retain previous data', async ({
215+
page,
216+
}) => {
217+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
218+
219+
await createNhsAppTemplatePage.loadPage(sessions.submitAndReturn.id);
220+
221+
const templateName = 'This is an NHS App template name';
222+
const templateMessage = 'This is an NHS App message';
223+
224+
await createNhsAppTemplatePage.nameInput.fill(templateName);
225+
226+
await createNhsAppTemplatePage.messageTextArea.fill(templateMessage);
227+
228+
await createNhsAppTemplatePage.clickContinueButton();
229+
230+
await page.getByRole('button', { name: 'Continue' }).click();
231+
232+
await expect(createNhsAppTemplatePage.nameInput).toHaveValue(
233+
templateName
234+
);
235+
236+
await expect(createNhsAppTemplatePage.messageTextArea).toHaveValue(
237+
templateMessage
238+
);
239+
});
240+
});
241+
242+
test.describe('Error handling', () => {
243+
test('when user visits page with mismatched template journey, then an invalid session error is displayed', async ({
244+
baseURL,
245+
page,
246+
}) => {
247+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
248+
249+
await createNhsAppTemplatePage.loadPage(sessions.noNhsAppTemplateType.id);
250+
251+
await expect(page).toHaveURL(`${baseURL}/templates/invalid-session`);
252+
});
253+
254+
test('when user visits page with a fake session, then an invalid session error is displayed', async ({
255+
baseURL,
256+
page,
257+
}) => {
258+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
259+
260+
await createNhsAppTemplatePage.loadPage('/fake-session-id');
261+
262+
await expect(page).toHaveURL(`${baseURL}/templates/invalid-session`);
263+
});
264+
265+
test('when user submits form with no data, then errors are displayed', async ({
266+
page,
267+
}) => {
268+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
269+
270+
await createNhsAppTemplatePage.loadPage(sessions.empty.id);
271+
272+
await createNhsAppTemplatePage.clickContinueButton();
273+
274+
await expect(createNhsAppTemplatePage.errorSummary).toBeVisible();
275+
276+
await expect(
277+
createNhsAppTemplatePage.errorSummary.locator('h2')
278+
).toHaveText('There is a problem');
279+
280+
await expect(
281+
createNhsAppTemplatePage.errorSummary.locator(
282+
`[href="#nhsAppTemplateName"]`
283+
)
284+
).toBeVisible();
285+
286+
await expect(
287+
createNhsAppTemplatePage.errorSummary.locator(
288+
`[href="#nhsAppTemplateMessage"]`
289+
)
290+
).toBeVisible();
291+
});
292+
293+
test('when user submits form with no "Template name", then an error is displayed', async ({
294+
page,
295+
}) => {
296+
const errorMessage = 'Enter a template name';
297+
298+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
299+
300+
await createNhsAppTemplatePage.loadPage(sessions.empty.id);
301+
302+
await createNhsAppTemplatePage.messageTextArea.fill('template-message');
303+
304+
await createNhsAppTemplatePage.clickContinueButton();
305+
306+
const nhsAppNameErrorLink = createNhsAppTemplatePage.errorSummary.locator(
307+
`[href="#nhsAppTemplateName"]`
308+
);
309+
310+
await expect(nhsAppNameErrorLink).toHaveText(errorMessage);
311+
312+
await nhsAppNameErrorLink.click();
313+
314+
await expect(createNhsAppTemplatePage.nameInput).toBeFocused();
315+
});
316+
317+
test('when user submits form with no "Template message", then an error is displayed', async ({
318+
page,
319+
}) => {
320+
const errorMessage = 'Enter a template message';
321+
322+
const createNhsAppTemplatePage = new TemplateMgmtCreateNhsAppPage(page);
323+
324+
await createNhsAppTemplatePage.loadPage(sessions.empty.id);
325+
326+
await createNhsAppTemplatePage.nameInput.fill('template-name');
327+
328+
await createNhsAppTemplatePage.clickContinueButton();
329+
330+
const nhsAppMessageErrorLink =
331+
createNhsAppTemplatePage.errorSummary.locator(
332+
'[href="#nhsAppTemplateMessage"]'
333+
);
334+
335+
await expect(nhsAppMessageErrorLink).toHaveText(errorMessage);
336+
337+
await nhsAppMessageErrorLink.click();
338+
339+
await expect(createNhsAppTemplatePage.messageTextArea).toBeFocused();
340+
});
341+
});
342+
});

0 commit comments

Comments
 (0)