← full-stack-fastapi-template  /  frontend/tests/utils/mailcatcher.ts

1
import type { APIRequestContext } from "@playwright/test"
2
3
type Email = {
4
  id: number
5
  recipients: string[]
6
  subject: string
7
}
8
9
async function findEmail({
10
  request,
11
  filter,
12
}: {
13
  request: APIRequestContext
14
  filter?: (email: Email) => boolean
15
}) {
16
  const response = await request.get(`${process.env.MAILCATCHER_HOST}/messages`)
17
18
  let emails = await response.json()
19
20
  if (filter) {
21
    emails = emails.filter(filter)
22
  }
23
24
  const email = emails[emails.length - 1]
25
26
  if (email) {
27
    return email as Email
28
  }
29
30
  return null
31
}
32
33
export function findLastEmail({
34
  request,
35
  filter,
36
  timeout = 5000,
37
}: {
38
  request: APIRequestContext
39
  filter?: (email: Email) => boolean
40
  timeout?: number
41
}) {
42
  const timeoutPromise = new Promise<never>((_, reject) =>
43
    setTimeout(
44
      () => reject(new Error("Timeout while trying to get latest email")),
45
      timeout,
46
    ),
47
  )
48
49
  const checkEmails = async () => {
50
    while (true) {
51
      const emailData = await findEmail({ request, filter })
52
53
      if (emailData) {
54
        return emailData
55
      }
56
      // Wait for 100ms before checking again
57
      await new Promise((resolve) => setTimeout(resolve, 100))
58
    }
59
  }
60
61
  return Promise.race([timeoutPromise, checkEmails()])
62
}
63