← full-stack-fastapi-template  /  frontend/tests/reset-password.spec.ts

1
import { expect, test } from "@playwright/test"
2
import { findLastEmail } from "./utils/mailcatcher"
3
import { randomEmail, randomPassword } from "./utils/random"
4
import { logInUser, signUpNewUser } from "./utils/user"
5
6
test.use({ storageState: { cookies: [], origins: [] } })
7
8
test("Password Recovery title is visible", async ({ page }) => {
9
  await page.goto("/recover-password")
10
11
  await expect(
12
    page.getByRole("heading", { name: "Password Recovery" }),
13
  ).toBeVisible()
14
})
15
16
test("Input is visible, empty and editable", async ({ page }) => {
17
  await page.goto("/recover-password")
18
19
  await expect(page.getByTestId("email-input")).toBeVisible()
20
  await expect(page.getByTestId("email-input")).toHaveText("")
21
  await expect(page.getByTestId("email-input")).toBeEditable()
22
})
23
24
test("Continue button is visible", async ({ page }) => {
25
  await page.goto("/recover-password")
26
27
  await expect(page.getByRole("button", { name: "Continue" })).toBeVisible()
28
})
29
30
test("User can reset password successfully using the link", async ({
31
  page,
32
  request,
33
}) => {
34
  const fullName = "Test User"
35
  const email = randomEmail()
36
  const password = randomPassword()
37
  const newPassword = randomPassword()
38
39
  // Sign up a new user
40
  await signUpNewUser(page, fullName, email, password)
41
42
  await page.goto("/recover-password")
43
  await page.getByTestId("email-input").fill(email)
44
45
  await page.getByRole("button", { name: "Continue" }).click()
46
47
  const emailData = await findLastEmail({
48
    request,
49
    filter: (e) => e.recipients.includes(`<${email}>`),
50
    timeout: 5000,
51
  })
52
53
  await page.goto(
54
    `${process.env.MAILCATCHER_HOST}/messages/${emailData.id}.html`,
55
  )
56
57
  const selector = 'a[href*="/reset-password?token="]'
58
59
  let url = await page.getAttribute(selector, "href")
60
61
  // TODO: update var instead of doing a replace
62
  url = url!.replace("http://localhost/", "http://localhost:5173/")
63
64
  // Set the new password and confirm it
65
  await page.goto(url)
66
67
  await page.getByTestId("new-password-input").fill(newPassword)
68
  await page.getByTestId("confirm-password-input").fill(newPassword)
69
  await page.getByRole("button", { name: "Reset Password" }).click()
70
  await expect(page.getByText("Password updated successfully")).toBeVisible()
71
72
  // Check if the user is able to login with the new password
73
  await logInUser(page, email, newPassword)
74
})
75
76
test("Expired or invalid reset link", async ({ page }) => {
77
  const password = randomPassword()
78
  const invalidUrl = "/reset-password?token=invalidtoken"
79
80
  await page.goto(invalidUrl)
81
82
  await page.getByTestId("new-password-input").fill(password)
83
  await page.getByTestId("confirm-password-input").fill(password)
84
  await page.getByRole("button", { name: "Reset Password" }).click()
85
86
  await expect(page.getByText("Invalid token")).toBeVisible()
87
})
88
89
test("Weak new password validation", async ({ page, request }) => {
90
  const fullName = "Test User"
91
  const email = randomEmail()
92
  const password = randomPassword()
93
  const weakPassword = "123"
94
95
  // Sign up a new user
96
  await signUpNewUser(page, fullName, email, password)
97
98
  await page.goto("/recover-password")
99
  await page.getByTestId("email-input").fill(email)
100
  await page.getByRole("button", { name: "Continue" }).click()
101
102
  const emailData = await findLastEmail({
103
    request,
104
    filter: (e) => e.recipients.includes(`<${email}>`),
105
    timeout: 5000,
106
  })
107
108
  await page.goto(
109
    `${process.env.MAILCATCHER_HOST}/messages/${emailData.id}.html`,
110
  )
111
112
  const selector = 'a[href*="/reset-password?token="]'
113
  let url = await page.getAttribute(selector, "href")
114
  url = url!.replace("http://localhost/", "http://localhost:5173/")
115
116
  // Set a weak new password
117
  await page.goto(url)
118
  await page.getByTestId("new-password-input").fill(weakPassword)
119
  await page.getByTestId("confirm-password-input").fill(weakPassword)
120
  await page.getByRole("button", { name: "Reset Password" }).click()
121
122
  await expect(
123
    page.getByText("Password must be at least 8 characters"),
124
  ).toBeVisible()
125
})
126