diff --git a/frontend/tests/reset-password.spec.ts b/frontend/tests/reset-password.spec.ts index fa7be461c3..0cf5417c83 100644 --- a/frontend/tests/reset-password.spec.ts +++ b/frontend/tests/reset-password.spec.ts @@ -1,10 +1,12 @@ import { expect, test } from "@playwright/test" -import { emailUrl, findLastEmail } from "./utils/mailpit" +import { waitForEmailHtml } from "./utils/mailpit" import { randomEmail, randomPassword } from "./utils/random" import { logInUser, signUpNewUser } from "./utils/user" test.use({ storageState: { cookies: [], origins: [] } }) +const resetPath = "/reset-password?token=" + test("Password Recovery title is visible", async ({ page }) => { await page.goto("/recover-password") @@ -44,21 +46,17 @@ test("User can reset password successfully using the link", async ({ await page.getByRole("button", { name: "Continue" }).click() - const emailData = await findLastEmail({ + const emailHtml = await waitForEmailHtml({ request, query: `to:${email}`, - timeout: 5000, }) - await page.goto(emailUrl(emailData)) - - const selector = 'a[href*="/reset-password?token="]' - - const url = await page.getAttribute(selector, "href") - const resetUrl = new URL(url!) + expect(emailHtml).toContain(resetPath) + const resetUrl = emailHtml.match(/\/reset-password\?token=[^"]+/)?.[0] + expect(resetUrl).toBeDefined() // Set the new password and confirm it - await page.goto(`${resetUrl.pathname}${resetUrl.search}`) + await page.goto(resetUrl!) await page.getByTestId("new-password-input").fill(newPassword) await page.getByTestId("confirm-password-input").fill(newPassword) @@ -95,20 +93,17 @@ test("Weak new password validation", async ({ page, request }) => { await page.getByTestId("email-input").fill(email) await page.getByRole("button", { name: "Continue" }).click() - const emailData = await findLastEmail({ + const emailHtml = await waitForEmailHtml({ request, query: `to:${email}`, - timeout: 5000, }) - await page.goto(emailUrl(emailData)) - - const selector = 'a[href*="/reset-password?token="]' - const url = await page.getAttribute(selector, "href") - const resetUrl = new URL(url!) + expect(emailHtml).toContain(resetPath) + const resetUrl = emailHtml.match(/\/reset-password\?token=[^"]+/)?.[0] + expect(resetUrl).toBeDefined() // Set a weak new password - await page.goto(`${resetUrl.pathname}${resetUrl.search}`) + await page.goto(resetUrl!) await page.getByTestId("new-password-input").fill(weakPassword) await page.getByTestId("confirm-password-input").fill(weakPassword) await page.getByRole("button", { name: "Reset Password" }).click() diff --git a/frontend/tests/utils/mailpit.ts b/frontend/tests/utils/mailpit.ts index 92c02e280b..6fe8ae76fa 100644 --- a/frontend/tests/utils/mailpit.ts +++ b/frontend/tests/utils/mailpit.ts @@ -1,36 +1,10 @@ import type { APIRequestContext } from "@playwright/test" -type Address = { - Name: string - Address: string -} - -type Email = { +type EmailSummary = { ID: string - To: Address[] - Subject: string -} - -async function findEmail({ - request, - query, -}: { - request: APIRequestContext - query: string -}) { - const response = await request.get( - `${process.env.MAILPIT_HOST}/api/v1/search`, - { - params: { query, limit: 1 }, - }, - ) - - const { messages }: { messages: Email[] } = await response.json() - - return messages[0] ?? null } -export async function findLastEmail({ +export async function waitForEmailHtml({ request, query, timeout = 5000, @@ -42,10 +16,27 @@ export async function findLastEmail({ const deadline = Date.now() + timeout while (Date.now() < deadline) { - const email = await findEmail({ request, query }) + const response = await request.get( + `${process.env.MAILPIT_HOST}/api/v1/search`, + { + params: { query, limit: 1 }, + }, + ) + const { messages }: { messages: EmailSummary[] } = await response.json() + const email = messages[0] if (email) { - return email + const htmlResponse = await request.get( + `${process.env.MAILPIT_HOST}/view/${email.ID}.html`, + ) + + if (!htmlResponse.ok()) { + throw new Error( + `Could not get the HTML for email "${email.ID}": ${htmlResponse.status()}`, + ) + } + + return htmlResponse.text() } await new Promise((resolve) => setTimeout(resolve, 100)) @@ -53,7 +44,3 @@ export async function findLastEmail({ throw new Error(`Timeout while trying to get the latest email for "${query}"`) } - -export function emailUrl(email: Email) { - return `${process.env.MAILPIT_HOST}/view/${email.ID}.html` -}