Skip to content

Commit f7bef00

Browse files
committed
✅ Simplify password reset E2E tests
1 parent 6b5b886 commit f7bef00

2 files changed

Lines changed: 34 additions & 52 deletions

File tree

frontend/tests/reset-password.spec.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { expect, test } from "@playwright/test"
2-
import { emailUrl, findLastEmail } from "./utils/mailpit"
2+
import { waitForEmailHtml } from "./utils/mailpit"
33
import { randomEmail, randomPassword } from "./utils/random"
44
import { logInUser, signUpNewUser } from "./utils/user"
55

66
test.use({ storageState: { cookies: [], origins: [] } })
77

8+
const resetPath = "/reset-password?token="
9+
810
test("Password Recovery title is visible", async ({ page }) => {
911
await page.goto("/recover-password")
1012

@@ -44,21 +46,17 @@ test("User can reset password successfully using the link", async ({
4446

4547
await page.getByRole("button", { name: "Continue" }).click()
4648

47-
const emailData = await findLastEmail({
49+
const emailHtml = await waitForEmailHtml({
4850
request,
4951
query: `to:${email}`,
50-
timeout: 5000,
5152
})
5253

53-
await page.goto(emailUrl(emailData))
54-
55-
const selector = 'a[href*="/reset-password?token="]'
56-
57-
const url = await page.getAttribute(selector, "href")
58-
const resetUrl = new URL(url!)
54+
expect(emailHtml).toContain(resetPath)
55+
const resetUrl = emailHtml.match(/\/reset-password\?token=[^"]+/)?.[0]
56+
expect(resetUrl).toBeDefined()
5957

6058
// Set the new password and confirm it
61-
await page.goto(`${resetUrl.pathname}${resetUrl.search}`)
59+
await page.goto(resetUrl!)
6260

6361
await page.getByTestId("new-password-input").fill(newPassword)
6462
await page.getByTestId("confirm-password-input").fill(newPassword)
@@ -95,20 +93,17 @@ test("Weak new password validation", async ({ page, request }) => {
9593
await page.getByTestId("email-input").fill(email)
9694
await page.getByRole("button", { name: "Continue" }).click()
9795

98-
const emailData = await findLastEmail({
96+
const emailHtml = await waitForEmailHtml({
9997
request,
10098
query: `to:${email}`,
101-
timeout: 5000,
10299
})
103100

104-
await page.goto(emailUrl(emailData))
105-
106-
const selector = 'a[href*="/reset-password?token="]'
107-
const url = await page.getAttribute(selector, "href")
108-
const resetUrl = new URL(url!)
101+
expect(emailHtml).toContain(resetPath)
102+
const resetUrl = emailHtml.match(/\/reset-password\?token=[^"]+/)?.[0]
103+
expect(resetUrl).toBeDefined()
109104

110105
// Set a weak new password
111-
await page.goto(`${resetUrl.pathname}${resetUrl.search}`)
106+
await page.goto(resetUrl!)
112107
await page.getByTestId("new-password-input").fill(weakPassword)
113108
await page.getByTestId("confirm-password-input").fill(weakPassword)
114109
await page.getByRole("button", { name: "Reset Password" }).click()

frontend/tests/utils/mailpit.ts

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,10 @@
11
import type { APIRequestContext } from "@playwright/test"
22

3-
type Address = {
4-
Name: string
5-
Address: string
6-
}
7-
8-
type Email = {
3+
type EmailSummary = {
94
ID: string
10-
To: Address[]
11-
Subject: string
12-
}
13-
14-
async function findEmail({
15-
request,
16-
query,
17-
}: {
18-
request: APIRequestContext
19-
query: string
20-
}) {
21-
const response = await request.get(
22-
`${process.env.MAILPIT_HOST}/api/v1/search`,
23-
{
24-
params: { query, limit: 1 },
25-
},
26-
)
27-
28-
const { messages }: { messages: Email[] } = await response.json()
29-
30-
return messages[0] ?? null
315
}
326

33-
export async function findLastEmail({
7+
export async function waitForEmailHtml({
348
request,
359
query,
3610
timeout = 5000,
@@ -42,18 +16,31 @@ export async function findLastEmail({
4216
const deadline = Date.now() + timeout
4317

4418
while (Date.now() < deadline) {
45-
const email = await findEmail({ request, query })
19+
const response = await request.get(
20+
`${process.env.MAILPIT_HOST}/api/v1/search`,
21+
{
22+
params: { query, limit: 1 },
23+
},
24+
)
25+
const { messages }: { messages: EmailSummary[] } = await response.json()
26+
const email = messages[0]
4627

4728
if (email) {
48-
return email
29+
const htmlResponse = await request.get(
30+
`${process.env.MAILPIT_HOST}/view/${email.ID}.html`,
31+
)
32+
33+
if (!htmlResponse.ok()) {
34+
throw new Error(
35+
`Could not get the HTML for email "${email.ID}": ${htmlResponse.status()}`,
36+
)
37+
}
38+
39+
return htmlResponse.text()
4940
}
5041

5142
await new Promise((resolve) => setTimeout(resolve, 100))
5243
}
5344

5445
throw new Error(`Timeout while trying to get the latest email for "${query}"`)
5546
}
56-
57-
export function emailUrl(email: Email) {
58-
return `${process.env.MAILPIT_HOST}/view/${email.ID}.html`
59-
}

0 commit comments

Comments
 (0)