/** * API Client for E2E tests * Provides typed methods for API interactions */ import { APIRequestContext, request } from '@playwright/test'; export class ApiClient { private context: APIRequestContext | null = null; private baseUrl: string; private authToken: string | null = null; constructor(baseUrl: string = 'http://localhost:8000') { this.baseUrl = baseUrl; } async init() { this.context = await request.newContext({ baseURL: this.baseUrl, }); } async dispose() { await this.context?.dispose(); } setAuthToken(token: string) { this.authToken = token; } private getHeaders(): Record { const headers: Record = { 'Content-Type': 'application/json', }; if (this.authToken) { headers['Authorization'] = `Bearer ${this.authToken}`; } return headers; } // Auth endpoints async login(email: string, password: string) { if (!this.context) await this.init(); const response = await this.context!.post('/api/v1/auth/login', { data: { username: email, password }, }); if (response.ok()) { const data = await response.json(); this.authToken = data.access_token; } return response; } async register(email: string, password: string, fullName: string) { if (!this.context) await this.init(); return this.context!.post('/api/v1/auth/register', { data: { email, password, full_name: fullName }, }); } async refreshToken(refreshToken: string) { if (!this.context) await this.init(); return this.context!.post('/api/v1/auth/refresh', { data: { refresh_token: refreshToken }, }); } // Scenario endpoints async getScenarios(params?: { page?: number; page_size?: number; status?: string }) { if (!this.context) await this.init(); const searchParams = new URLSearchParams(); if (params?.page) searchParams.append('page', params.page.toString()); if (params?.page_size) searchParams.append('page_size', params.page_size.toString()); if (params?.status) searchParams.append('status', params.status); return this.context!.get(`/api/v1/scenarios?${searchParams}`, { headers: this.getHeaders(), }); } async getScenario(id: string) { if (!this.context) await this.init(); return this.context!.get(`/api/v1/scenarios/${id}`, { headers: this.getHeaders(), }); } async createScenario(data: { name: string; description?: string; region: string; tags?: string[]; }) { if (!this.context) await this.init(); return this.context!.post('/api/v1/scenarios', { data, headers: this.getHeaders(), }); } async updateScenario(id: string, data: Partial<{ name: string; description: string; region: string; tags: string[]; }>) { if (!this.context) await this.init(); return this.context!.put(`/api/v1/scenarios/${id}`, { data, headers: this.getHeaders(), }); } async deleteScenario(id: string) { if (!this.context) await this.init(); return this.context!.delete(`/api/v1/scenarios/${id}`, { headers: this.getHeaders(), }); } // Metrics endpoints async getDashboardMetrics() { if (!this.context) await this.init(); return this.context!.get('/api/v1/metrics/dashboard', { headers: this.getHeaders(), }); } async getScenarioMetrics(scenarioId: string) { if (!this.context) await this.init(); return this.context!.get(`/api/v1/scenarios/${scenarioId}/metrics`, { headers: this.getHeaders(), }); } // Report endpoints async getReports(scenarioId: string) { if (!this.context) await this.init(); return this.context!.get(`/api/v1/scenarios/${scenarioId}/reports`, { headers: this.getHeaders(), }); } async generateReport(scenarioId: string, format: 'pdf' | 'csv', includeLogs: boolean = true) { if (!this.context) await this.init(); return this.context!.post(`/api/v1/scenarios/${scenarioId}/reports`, { data: { format, include_logs: includeLogs }, headers: this.getHeaders(), }); } // Ingest endpoints async ingestLog(scenarioId: string, log: { message: string; source?: string; level?: string; metadata?: Record; }) { if (!this.context) await this.init(); return this.context!.post('/ingest', { data: log, headers: { ...this.getHeaders(), 'X-Scenario-ID': scenarioId, }, }); } // Health check async healthCheck() { if (!this.context) await this.init(); return this.context!.get('/health'); } }