import { APIRequestContext, request } from "@playwright/test" import { ADMIN_TOKEN, API_BASE } from "../../fixtures/test-constants" let adminContext: APIRequestContext | null = null /** * Get or create a singleton admin API context with the ADMIN_TOKEN. */ async function getAdminContext(baseURL: string): Promise { if (!adminContext) { adminContext = await request.newContext({ baseURL, ignoreHTTPSErrors: true, extraHTTPHeaders: { Token: ADMIN_TOKEN, }, }) } return adminContext } /** * Delete a user by ID via admin API. */ export async function deleteUser(baseURL: string, userId: string): Promise { const ctx = await getAdminContext(baseURL) const res = await ctx.delete(`${API_BASE}/user/${userId}`) return res.ok() } /** * Cleanup test users matching a pattern in their email. */ export async function cleanupTestUsers(baseURL: string, emailPattern: RegExp | string): Promise { const ctx = await getAdminContext(baseURL) const res = await ctx.get(`${API_BASE}/user`) if (!res.ok()) return 0 const users: { id?: string; _id?: string; email?: string }[] = await res.json() if (!Array.isArray(users)) return 0 let deleted = 0 for (const user of users) { const email = user.email || "" const matches = typeof emailPattern === "string" ? email.includes(emailPattern) : emailPattern.test(email) if (matches) { const userId = user.id || user._id if (userId) { const ok = await deleteUser(baseURL, userId) if (ok) deleted++ } } } return deleted } /** * Cleanup all test data (users and tokens matching @test.example.com). */ export async function cleanupAllTestData(baseURL: string): Promise<{ users: number }> { const testPattern = "@test.example.com" const users = await cleanupTestUsers(baseURL, testPattern) return { users } } /** * Dispose the admin API context. Call in globalTeardown. */ export async function disposeAdminApi(): Promise { if (adminContext) { await adminContext.dispose() adminContext = null } }