Skip to content

Commit 8efef66

Browse files
authored
✨ Add User Settings e2e tests (#1271)
1 parent c8b1b3a commit 8efef66

3 files changed

Lines changed: 291 additions & 3 deletions

File tree

frontend/src/components/UserSettings/ChangePassword.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const ChangePassword = () => {
3838
mutationFn: (data: UpdatePassword) =>
3939
UsersService.updatePasswordMe({ requestBody: data }),
4040
onSuccess: () => {
41-
showToast("Success!", "Password updated.", "success")
41+
showToast("Success!", "Password updated successfully.", "success")
4242
reset()
4343
},
4444
onError: (err: ApiError) => {
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
import { expect, test } from "@playwright/test"
2+
import { randomEmail } from "./utils/random"
3+
import { logInUser, logOutUser, signUpNewUser } from "./utils/user"
4+
import { firstSuperuser, firstSuperuserPassword } from "./config.ts"
5+
6+
const tabs = ["My profile", "Password", "Appearance"]
7+
8+
// User Information
9+
10+
test("My profile tab is active by default", async ({ page }) => {
11+
await page.goto("/settings")
12+
await expect(page.getByRole("tab", { name: "My profile" })).toHaveAttribute(
13+
"aria-selected",
14+
"true",
15+
)
16+
})
17+
18+
test("All tabs are visible", async ({ page }) => {
19+
await page.goto("/settings")
20+
for (const tab of tabs) {
21+
await expect(page.getByRole("tab", { name: tab })).toBeVisible()
22+
}
23+
})
24+
25+
test.describe("Edit user full name and email successfully", () => {
26+
test.use({ storageState: { cookies: [], origins: [] } })
27+
28+
test("Edit user name with a valid name", async ({ page }) => {
29+
const fullName = "Test User"
30+
const email = randomEmail()
31+
const updatedName = "Test User 2"
32+
const password = "password"
33+
34+
// Sign up a new user
35+
await signUpNewUser(page, fullName, email, password)
36+
37+
// Log in the user
38+
await logInUser(page, email, password)
39+
40+
await page.goto("/settings")
41+
await page.getByRole("tab", { name: "My profile" }).click()
42+
await page.getByRole("button", { name: "Edit" }).click()
43+
await page.getByLabel("Full name").fill(updatedName)
44+
await page.getByRole("button", { name: "Save" }).click()
45+
await expect(page.getByText("User updated successfully")).toBeVisible()
46+
// Check if the new name is displayed on the page
47+
await expect(
48+
page.getByLabel("My profile").getByText(updatedName, { exact: true }),
49+
).toBeVisible()
50+
})
51+
52+
test("Edit user email with a valid email", async ({ page }) => {
53+
const fullName = "Test User"
54+
const email = randomEmail()
55+
const updatedEmail = randomEmail()
56+
const password = "password"
57+
58+
// Sign up a new user
59+
await signUpNewUser(page, fullName, email, password)
60+
61+
// Log in the user
62+
await logInUser(page, email, password)
63+
64+
await page.goto("/settings")
65+
await page.getByRole("tab", { name: "My profile" }).click()
66+
await page.getByRole("button", { name: "Edit" }).click()
67+
await page.getByLabel("Email").fill(updatedEmail)
68+
await page.getByRole("button", { name: "Save" }).click()
69+
await expect(page.getByText("User updated successfully")).toBeVisible()
70+
await expect(
71+
page.getByLabel("My profile").getByText(updatedEmail, { exact: true }),
72+
).toBeVisible()
73+
})
74+
})
75+
76+
test.describe("Edit user with invalid data", () => {
77+
test.use({ storageState: { cookies: [], origins: [] } })
78+
79+
test("Edit user email with an invalid email", async ({ page }) => {
80+
const fullName = "Test User"
81+
const email = randomEmail()
82+
const password = "password"
83+
const invalidEmail = ""
84+
85+
// Sign up a new user
86+
await signUpNewUser(page, fullName, email, password)
87+
88+
// Log in the user
89+
await logInUser(page, email, password)
90+
91+
await page.goto("/settings")
92+
await page.getByRole("tab", { name: "My profile" }).click()
93+
await page.getByRole("button", { name: "Edit" }).click()
94+
await page.getByLabel("Email").fill(invalidEmail)
95+
await page.locator("body").click()
96+
await expect(page.getByText("Email is required")).toBeVisible()
97+
})
98+
99+
test("Cancel edit action restores original name", async ({ page }) => {
100+
const fullName = "Test User"
101+
const email = randomEmail()
102+
const password = "password"
103+
const updatedName = "Test User"
104+
105+
// Sign up a new user
106+
await signUpNewUser(page, fullName, email, password)
107+
108+
// Log in the user
109+
await logInUser(page, email, password)
110+
111+
await page.goto("/settings")
112+
await page.getByRole("tab", { name: "My profile" }).click()
113+
await page.getByRole("button", { name: "Edit" }).click()
114+
await page.getByLabel("Full name").fill(updatedName)
115+
await page.getByRole("button", { name: "Cancel" }).first().click()
116+
await expect(
117+
page.getByLabel("My profile").getByText(fullName, { exact: true }),
118+
).toBeVisible()
119+
})
120+
121+
test("Cancel edit action restores original email", async ({ page }) => {
122+
const fullName = "Test User"
123+
const email = randomEmail()
124+
const password = "password"
125+
const updatedEmail = randomEmail()
126+
127+
// Sign up a new user
128+
await signUpNewUser(page, fullName, email, password)
129+
130+
// Log in the user
131+
await logInUser(page, email, password)
132+
133+
await page.goto("/settings")
134+
await page.getByRole("tab", { name: "My profile" }).click()
135+
await page.getByRole("button", { name: "Edit" }).click()
136+
await page.getByLabel("Email").fill(updatedEmail)
137+
await page.getByRole("button", { name: "Cancel" }).first().click()
138+
await expect(
139+
page.getByLabel("My profile").getByText(email, { exact: true }),
140+
).toBeVisible()
141+
})
142+
})
143+
144+
// Change Password
145+
146+
test.describe("Change password successfully", () => {
147+
test.use({ storageState: { cookies: [], origins: [] } })
148+
149+
test("Update password successfully", async ({ page }) => {
150+
const fullName = "Test User"
151+
const email = randomEmail()
152+
const password = "password"
153+
const NewPassword = "newPassword"
154+
155+
// Sign up a new user
156+
await signUpNewUser(page, fullName, email, password)
157+
158+
// Log in the user
159+
await logInUser(page, email, password)
160+
161+
await page.goto("/settings")
162+
await page.getByRole("tab", { name: "Password" }).click()
163+
await page.getByLabel("Current Password*").fill(password)
164+
await page.getByLabel("Set Password*").fill(NewPassword)
165+
await page.getByLabel("Confirm Password*").fill(NewPassword)
166+
await page.getByRole("button", { name: "Save" }).click()
167+
await expect(page.getByText("Password updated successfully.")).toBeVisible()
168+
169+
await logOutUser(page)
170+
171+
// Check if the user can log in with the new password
172+
await logInUser(page, email, NewPassword)
173+
})
174+
})
175+
176+
test.describe("Change password with invalid data", () => {
177+
test.use({ storageState: { cookies: [], origins: [] } })
178+
179+
test("Update password with weak passwords", async ({ page }) => {
180+
const fullName = "Test User"
181+
const email = randomEmail()
182+
const password = "password"
183+
const weakPassword = "weak"
184+
185+
// Sign up a new user
186+
await signUpNewUser(page, fullName, email, password)
187+
188+
// Log in the user
189+
await logInUser(page, email, password)
190+
191+
await page.goto("/settings")
192+
await page.getByRole("tab", { name: "Password" }).click()
193+
await page.getByLabel("Current Password*").fill(password)
194+
await page.getByLabel("Set Password*").fill(weakPassword)
195+
await page.getByLabel("Confirm Password*").fill(weakPassword)
196+
await expect(
197+
page.getByText("Password must be at least 8 characters"),
198+
).toBeVisible()
199+
})
200+
201+
test("New password and confirmation password do not match", async ({
202+
page,
203+
}) => {
204+
const fullName = "Test User"
205+
const email = randomEmail()
206+
const password = "password"
207+
const newPassword = "newPassword"
208+
const confirmPassword = "confirmPassword"
209+
210+
// Sign up a new user
211+
await signUpNewUser(page, fullName, email, password)
212+
213+
// Log in the user
214+
await logInUser(page, email, password)
215+
216+
await page.goto("/settings")
217+
await page.getByRole("tab", { name: "Password" }).click()
218+
await page.getByLabel("Current Password*").fill(password)
219+
await page.getByLabel("Set Password*").fill(newPassword)
220+
await page.getByLabel("Confirm Password*").fill(confirmPassword)
221+
await page.getByRole("button", { name: "Save" }).click()
222+
await expect(page.getByText("Passwords do not match")).toBeVisible()
223+
})
224+
225+
test("Current password and new password are the same", async ({ page }) => {
226+
const fullName = "Test User"
227+
const email = randomEmail()
228+
const password = "password"
229+
230+
// Sign up a new user
231+
await signUpNewUser(page, fullName, email, password)
232+
233+
// Log in the user
234+
await logInUser(page, email, password)
235+
236+
await page.goto("/settings")
237+
await page.getByRole("tab", { name: "Password" }).click()
238+
await page.getByLabel("Current Password*").fill(password)
239+
await page.getByLabel("Set Password*").fill(password)
240+
await page.getByLabel("Confirm Password*").fill(password)
241+
await page.getByRole("button", { name: "Save" }).click()
242+
await expect(
243+
page.getByText("New password cannot be the same as the current one"),
244+
).toBeVisible()
245+
})
246+
})
247+
248+
// Appearance
249+
250+
test("Appearance tab is visible", async ({ page }) => {
251+
await page.goto("/settings")
252+
await page.getByRole("tab", { name: "Appearance" }).click()
253+
await expect(page.getByLabel("Appearance")).toBeVisible()
254+
})
255+
256+
test("User can switch from light mode to dark mode", async ({ page }) => {
257+
await page.goto("/settings")
258+
await page.getByRole("tab", { name: "Appearance" }).click()
259+
await page.getByLabel("Appearance").locator("span").nth(3).click()
260+
const isDarkMode = await page.evaluate(() =>
261+
document.body.classList.contains("chakra-ui-dark"),
262+
)
263+
expect(isDarkMode).toBe(true)
264+
})
265+
266+
test("User can switch from dark mode to light mode", async ({ page }) => {
267+
await page.goto("/settings")
268+
await page.getByRole("tab", { name: "Appearance" }).click()
269+
await page.getByLabel("Appearance").locator("span").first().click()
270+
const isLightMode = await page.evaluate(() =>
271+
document.body.classList.contains("chakra-ui-light"),
272+
)
273+
expect(isLightMode).toBe(true)
274+
})
275+
276+
test("Selected mode is preserved across sessions", async ({ page }) => {
277+
await page.goto("/settings")
278+
await page.getByRole("tab", { name: "Appearance" }).click()
279+
await page.getByLabel("Appearance").locator("span").nth(3).click()
280+
281+
await logOutUser(page)
282+
283+
await logInUser(page, firstSuperuser, firstSuperuserPassword)
284+
const isDarkMode = await page.evaluate(() =>
285+
document.body.classList.contains("chakra-ui-dark"),
286+
)
287+
expect(isDarkMode).toBe(true)
288+
})

frontend/tests/utils/user.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ export async function logInUser(page: Page, email: string, password: string) {
3131
).toBeVisible()
3232
}
3333

34-
export async function logOutUser(page: Page, name: string) {
35-
await page.getByRole("button", { name: name }).click()
34+
export async function logOutUser(page: Page) {
35+
await page.getByTestId("user-menu").click()
3636
await page.getByRole("menuitem", { name: "Log out" }).click()
3737
await page.goto("/login")
3838
}

0 commit comments

Comments
 (0)