import type { APIRequestContext } from '@playwright/test'; import { adminApi } from './api'; // Resources to delete after a test, in LIFO order. Tests register // their creations and the registry tears everything down in // `cleanupRegistered` — typically called from `test.afterEach`. type Cleanup = (api: APIRequestContext) => Promise; export class CleanupRegistry { private items: Cleanup[] = []; app(slugOrId: string): void { this.items.push(async (api) => { await api.delete(`/api/v1/admin/apps/${encodeURIComponent(slugOrId)}?force=true`); }); } adminUser(userId: string): void { this.items.push(async (api) => { await api.delete(`/api/v1/admin/admins/${userId}`); }); } apiKey(keyId: string): void { this.items.push(async (api) => { await api.delete(`/api/v1/admin/api-keys/${keyId}`); }); } async run(): Promise { if (this.items.length === 0) return; const api = await adminApi(); try { for (const item of this.items.reverse()) { try { await item(api); } catch { // Best-effort cleanup — a missing resource (already // deleted by the test) shouldn't fail the suite. } } } finally { await api.dispose(); this.items = []; } } }