Milestone A of the frontend test plan. Sets up the test rig — config, globalSetup that probes the backend and seeds an admin session into storageState, lightweight fixtures, and a 3-test smoke spec — without yet covering any user journeys (those land in Milestone B). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
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<void>;
|
|
|
|
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<void> {
|
|
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 = [];
|
|
}
|
|
}
|
|
}
|