Skip to content

Commit 548706e

Browse files
committed
E2E : Created create-user-account POM for tests and adapted existing test to use it
1 parent e8d8ccc commit 548706e

3 files changed

Lines changed: 428 additions & 276 deletions

File tree

Lines changed: 75 additions & 276 deletions
Original file line numberDiff line numberDiff line change
@@ -1,323 +1,122 @@
1-
import { test, expect, Page } from "@playwright/test";
1+
import { expect, test } from "@playwright/test";
22
import { loginAsServerAdmin } from "../utils/authenticate";
3-
import {
4-
generateUniqueUsername,
5-
navigateTo,
6-
selectVuetifyOptionByName,
7-
expectToHaveUrl,
8-
} from "../utils/helpers";
3+
import { generateUniqueUsername } from "../utils/helpers";
4+
import { PlaywrightCreateUserAccountPage } from "../models/playwright-create-user-account-page";
5+
import { PlaywrightUserAccountsPage } from "../models/playwright-user-accounts-page";
96

10-
async function setupCreateUserAccountPage(page: Page) {
11-
await expect(
12-
page.getByTestId("createUserAccount-form-container"),
13-
).toBeVisible();
14-
15-
//selects
16-
const institutionSelectLocator = page.getByTestId(
17-
"createUserAccount-institution-select",
18-
);
19-
const roleSelectLocator = page.getByTestId("createUserAccount-role-select");
20-
21-
// fields
22-
const usernameLocator = page.getByLabel(/username/i);
23-
const nameLocator = page
24-
.getByTestId("createUserAccount-name-input")
25-
.getByRole("textbox");
26-
const surnameLocator = page
27-
.getByTestId("createUserAccount-surname-input")
28-
.getByRole("textbox");
29-
const emailLocator = page
30-
.getByTestId("createUserAccount-email-input")
31-
.getByRole("textbox");
32-
33-
const passwordLocator = page
34-
.getByTestId("createUserAccount-password-input")
35-
.getByRole("textbox");
36-
const confirmPasswordLocator = page
37-
.getByTestId("createUserAccount-confirmPassword-input")
38-
.getByRole("textbox");
39-
40-
// buttons
41-
const saveButtonLocator = page.getByTestId("createUserAccount-save-button");
42-
const cancelButtonLocator = page.getByTestId(
43-
"createUserAccount-cancel-button",
44-
);
45-
46-
return {
47-
institutionSelectLocator,
48-
usernameLocator,
49-
nameLocator,
50-
surnameLocator,
51-
emailLocator,
52-
passwordLocator,
53-
confirmPasswordLocator,
54-
roleSelectLocator,
55-
saveButtonLocator,
56-
cancelButtonLocator,
57-
};
58-
}
59-
60-
//TODO this test was left with kinda big redundancies to explain to the apprentices in simple terms what is going on. Small refactor later
617
test.describe("1.1 User Accounts - CREATE Add", () => {
8+
let createUserAccountPage: PlaywrightCreateUserAccountPage;
9+
6210
test.beforeEach(async ({ page }) => {
6311
await loginAsServerAdmin(page);
64-
await navigateTo(page, "/user-accounts/create");
12+
13+
const userAccountsPage = new PlaywrightUserAccountsPage(page);
14+
await userAccountsPage.goto();
15+
await userAccountsPage.expectVisible();
16+
17+
createUserAccountPage =
18+
await userAccountsPage.navigateToCreateUserAccount();
19+
await createUserAccountPage.expectVisible();
6520
});
6621

6722
test("A Success - creates a new INACTIVE user account", async ({
6823
page,
6924
}) => {
70-
const {
71-
institutionSelectLocator,
72-
usernameLocator,
73-
nameLocator,
74-
surnameLocator,
75-
emailLocator,
76-
passwordLocator,
77-
confirmPasswordLocator,
78-
roleSelectLocator,
79-
saveButtonLocator,
80-
} = await setupCreateUserAccountPage(page);
25+
expect(page.url()).toContain("/user-accounts/create");
8126

8227
const uniqueValue = generateUniqueUsername("e2e-1.1.A-Success");
8328

84-
//define values to be filled in
85-
const username = uniqueValue;
86-
const name = uniqueValue + "Name";
87-
const surname = uniqueValue + "LastName";
88-
const email = uniqueValue + "@email.com";
89-
const password = "StrongPass123!";
90-
91-
const institutionToSelect = "SEB Server";
92-
const roleToSelect = "Server Administrator";
93-
94-
// fill selects
95-
await selectVuetifyOptionByName(
96-
page,
97-
institutionSelectLocator,
98-
institutionToSelect,
99-
);
100-
await selectVuetifyOptionByName(page, roleSelectLocator, roleToSelect);
101-
102-
//fill fields
103-
await usernameLocator.fill(username);
104-
await nameLocator.fill(name);
105-
await surnameLocator.fill(surname);
106-
await emailLocator.fill(email);
107-
await passwordLocator.fill(password);
108-
await confirmPasswordLocator.fill(password);
109-
110-
//create api interceptors befrre clicking save
111-
const createRequestPromise = page.waitForRequest((req) => {
112-
return (
113-
req.method() === "POST" &&
114-
/\/useraccount(?:\?|$)/i.test(req.url())
115-
);
29+
await createUserAccountPage.fillForm({
30+
institutionName: "SEB Server",
31+
roleName: "Server Administrator",
32+
username: `${uniqueValue}Username`,
33+
name: `${uniqueValue}Name`,
34+
surname: `${uniqueValue}LastName`,
35+
email: `${uniqueValue}@email.com`,
36+
pickFirstTimezone: true,
37+
password: "StrongPass123!",
38+
confirmPassword: "StrongPass123!",
11639
});
11740

118-
const createResponsePromise = page.waitForResponse((resp) => {
119-
return (
120-
resp.request().method() === "POST" &&
121-
/\/useraccount(?:\?|$)/i.test(resp.url())
122-
);
41+
await createUserAccountPage.expectCreateRequestSucceeded(async () => {
42+
await createUserAccountPage.submit();
12343
});
12444

125-
// click save
126-
await saveButtonLocator.click();
127-
128-
// capture req and resp
129-
const createRequest = await createRequestPromise;
130-
const createResponse = await createResponsePromise;
131-
132-
// assert endpoint aand method, then status
133-
expect(createRequest.method()).toBe("POST");
134-
expect(createRequest.url()).toMatch(/\/useraccount(?:\?|$)/i);
135-
136-
expect(createResponse.status()).toBe(200);
137-
expect(createResponse.ok()).toBeTruthy();
138-
139-
// assert payload
140-
const actualPayload = createRequest.postDataJSON();
141-
142-
//this needs to match the fields we filled out above
143-
const expectedPayload = {
144-
institutionId: "11", //this matches SQL script for e2e testing!!! it corresponds to SEB Server institution
145-
name: name,
146-
surname: surname,
147-
username: username,
148-
newPassword: password,
149-
confirmNewPassword: password,
150-
language: "en",
151-
email: email,
152-
userRoles: ["SEB_SERVER_ADMIN"],
153-
};
154-
155-
expect(actualPayload).toMatchObject(expectedPayload);
156-
157-
await expectToHaveUrl(page, "user-accounts");
158-
159-
//note that this test does not test if the backend actually saves the data correctly. This could be done in 2 ways:
160-
// 1: Navigate to User accounts, search for the username entered in the test, and look at the details - This however creates a dependency on get all, and get by id working. If one of those is broken, this test would fail too
161-
// 2: Clean way, set up a database query to actually verify the data is entered correct in the tables - This would be the clean way
45+
await createUserAccountPage.expectRedirectToUserAccounts();
16246
});
16347

164-
test("B Client Validation - checks all validations and that create button doesn't do API call", async ({
48+
test("B Client Validation - shows validation messages and does NOT call create API", async ({
16549
page,
16650
}) => {
167-
const { passwordLocator, confirmPasswordLocator, saveButtonLocator } =
168-
await setupCreateUserAccountPage(page);
169-
170-
// mo post request allowed during this test (well none should get through)
171-
await page.route(/\/useraccount(?:\?|$)/i, async (route, request) => {
172-
if (request.method() === "POST") {
173-
await route.abort();
174-
throw new Error(
175-
"POST /useraccount was attempted during failed client validation test",
176-
);
177-
}
178-
await route.continue();
179-
});
180-
181-
page.on("request", (req) => {
182-
if (
183-
req.method() === "POST" &&
184-
/\/useraccount(?:\?|$)/i.test(req.url())
185-
) {
186-
throw new Error(
187-
`Validation test must not call POST /useraccount, but it did: ${req.url()}`,
188-
);
189-
}
190-
});
191-
192-
async function expectFieldError(testId: string, text: string) {
193-
const field = page.getByTestId(testId);
194-
await expect(
195-
field.locator(".v-messages__message").filter({ hasText: text }),
196-
).toHaveCount(1, { timeout: 5000 });
197-
}
51+
expect(page.url()).toContain("/user-accounts/create");
19852

19953
const REQUIRED = "This field is required";
20054
const PASSWORD_TOO_SHORT = "Password must be at least 8 characters";
20155
const PASSWORDS_MUST_MATCH = "Passwords must match";
20256

203-
// 1. Click with all empty
204-
await saveButtonLocator.click();
205-
206-
await expectFieldError(
207-
"createUserAccount-institution-select",
208-
REQUIRED,
209-
);
210-
await expectFieldError("createUserAccount-username-input", REQUIRED);
211-
await expectFieldError("createUserAccount-name-input", REQUIRED);
212-
await expectFieldError("createUserAccount-surname-input", REQUIRED);
213-
await expectFieldError("createUserAccount-password-input", REQUIRED);
214-
await expectFieldError(
215-
"createUserAccount-confirmPassword-input",
216-
REQUIRED,
217-
);
218-
await expectFieldError("createUserAccount-role-select", REQUIRED);
219-
220-
// 2. Too short password
221-
await passwordLocator.fill("Abc1"); // < 8
222-
await saveButtonLocator.click();
57+
await createUserAccountPage.expectNoCreateRequest(async () => {
58+
await createUserAccountPage.submit();
59+
});
22360

224-
await expectFieldError(
225-
"createUserAccount-password-input",
226-
PASSWORD_TOO_SHORT,
227-
);
61+
await createUserAccountPage.expectRequiredFieldErrors({
62+
institution: REQUIRED,
63+
username: REQUIRED,
64+
name: REQUIRED,
65+
surname: REQUIRED,
66+
password: REQUIRED,
67+
confirmPassword: REQUIRED,
68+
role: REQUIRED,
69+
});
22870

229-
// 3. missmatch passwords
230-
await passwordLocator.fill("Abcdefg1");
231-
await confirmPasswordLocator.fill("Abcdefg2");
232-
await saveButtonLocator.click();
71+
await createUserAccountPage.fillPassword("Abc1");
72+
await createUserAccountPage.expectNoCreateRequest(async () => {
73+
await createUserAccountPage.submit();
74+
});
75+
await createUserAccountPage.expectPasswordTooShort(PASSWORD_TOO_SHORT);
23376

234-
await expectFieldError(
235-
"createUserAccount-confirmPassword-input",
77+
await createUserAccountPage.fillPassword("Abcdefg1");
78+
await createUserAccountPage.fillConfirmPassword("Abcdefg2");
79+
await createUserAccountPage.expectNoCreateRequest(async () => {
80+
await createUserAccountPage.submit();
81+
});
82+
await createUserAccountPage.expectPasswordsMustMatch(
23683
PASSWORDS_MUST_MATCH,
23784
);
23885

239-
// expected to not change URL
240-
await expectToHaveUrl(page, "user-accounts/create");
86+
await createUserAccountPage.expectStillOnCreatePage();
24187
});
24288

243-
test("C Server Error - user account already exists (duplicate username)", async ({
89+
test("C Server Error - duplicate username shows toast", async ({
24490
page,
24591
}) => {
246-
const {
247-
institutionSelectLocator,
248-
usernameLocator,
249-
nameLocator,
250-
surnameLocator,
251-
emailLocator,
252-
passwordLocator,
253-
confirmPasswordLocator,
254-
roleSelectLocator,
255-
saveButtonLocator,
256-
} = await setupCreateUserAccountPage(page);
92+
expect(page.url()).toContain("/user-accounts/create");
25793

25894
const uniqueValue = generateUniqueUsername("e2e-1.1.C-Server-Error");
25995

260-
const username = "createtests"; // SQL Script includes a user with this username!!!
261-
const name = uniqueValue + "Name";
262-
const surname = uniqueValue + "LastName";
263-
const email = uniqueValue + "@email.com";
264-
const password = "StrongPass123!";
265-
266-
const institutionToSelect = "SEB Server";
267-
const roleToSelect = "Server Administrator";
268-
269-
// fill selects
270-
await selectVuetifyOptionByName(
271-
page,
272-
institutionSelectLocator,
273-
institutionToSelect,
274-
);
275-
await selectVuetifyOptionByName(page, roleSelectLocator, roleToSelect);
276-
277-
//fill fields
278-
await usernameLocator.fill(username);
279-
await nameLocator.fill(name);
280-
await surnameLocator.fill(surname);
281-
await emailLocator.fill(email);
282-
await passwordLocator.fill(password);
283-
await confirmPasswordLocator.fill(password);
284-
285-
const createRequestPromise = page.waitForRequest((req) => {
286-
return (
287-
req.method() === "POST" &&
288-
/\/useraccount(?:\?|$)/i.test(req.url())
289-
);
96+
await createUserAccountPage.fillForm({
97+
institutionName: "SEB Server",
98+
roleName: "Server Administrator",
99+
username: "createtests", //there should be a db entry with username createtests
100+
name: `${uniqueValue}Name`,
101+
surname: `${uniqueValue}LastName`,
102+
email: `${uniqueValue}@email.com`,
103+
password: "StrongPass123!",
104+
confirmPassword: "StrongPass123!",
290105
});
291106

292-
const createResponsePromise = page.waitForResponse((resp) => {
293-
return (
294-
resp.request().method() === "POST" &&
295-
/\/useraccount(?:\?|$)/i.test(resp.url())
296-
);
297-
});
298-
299-
await saveButtonLocator.click();
300-
301-
const createRequest = await createRequestPromise;
302-
const createResponse = await createResponsePromise;
303-
304-
expect(createRequest.method()).toBe("POST");
305-
expect(createRequest.url()).toMatch(/\/useraccount(?:\?|$)/i);
306-
307-
expect(createResponse.status()).toBe(400);
308-
expect(createResponse.ok()).toBeFalsy();
309-
310-
await expectToHaveUrl(page, "user-accounts/create");
311-
//check toast
312-
const toast = page.locator(".toast-item[role='alert']");
107+
const resp = await createUserAccountPage.captureCreateResponse(
108+
async () => {
109+
await createUserAccountPage.submit();
110+
},
111+
);
313112

314-
await expect(toast).toBeVisible();
113+
expect(resp.status()).toBe(400);
114+
expect(resp.ok()).toBeFalsy();
315115

316-
await expect(toast.locator(".toast-text")).toContainText(
116+
await createUserAccountPage.expectStillOnCreatePage();
117+
await createUserAccountPage.expectErrorToast([
317118
"Field validation error",
318-
);
319-
await expect(toast.locator(".toast-text")).toContainText(
320119
"Username is already being used.",
321-
);
120+
]);
322121
});
323122
});

0 commit comments

Comments
 (0)