// tests/e2e/system-verification.spec.ts // E2E Verification Script for C# .NET API Server, Auth, LLM Proxy, Usage Costing, and BackOffice import { test, expect } from '@playwright/test' const API_BASE = 'http://localhost:5000' test.describe('D3RO Voice E2E Architecture Verification', () => { let authToken = '' const testEmail = `e2e_user_${Date.now()}@d3ro.ai` const testPassword = 'Password123!' test('1. API Server Health & Initial Endpoints', async ({ request }) => { const response = await request.get(`${API_BASE}/api/admin/stats`) expect(response.status()).toBe(200) const stats = await response.json() expect(stats).toHaveProperty('totalUsers') expect(stats).toHaveProperty('serverUptimeSeconds') expect(stats).toHaveProperty('totalCost') console.log('✓ Stats verified:', stats) }) test('2. User Registration & Login (Mandatory Online Auth)', async ({ request }) => { // Register const regRes = await request.post(`${API_BASE}/api/auth/register`, { data: { email: testEmail, password: testPassword } }) expect(regRes.status()).toBe(200) const regData = await regRes.json() expect(regData).toHaveProperty('token') expect(regData.email).toBe(testEmail) console.log('✓ User Registration successful:', regData.email) // Login const loginRes = await request.post(`${API_BASE}/api/auth/login`, { data: { email: testEmail, password: testPassword } }) expect(loginRes.status()).toBe(200) const loginData = await loginRes.json() expect(loginData).toHaveProperty('token') authToken = loginData.token console.log('✓ User Login successful, JWT issued.') }) test('3. Dynamic Model Endpoint Management (Admin)', async ({ request }) => { const newModel = { modelId: `e2e-custom-model-${Date.now()}`, modelName: 'E2E Dynamic Custom LLM', provider: 'CustomProvider', endpointUrl: 'https://api.openai.com/v1/chat/completions', apiKey: 'sk-e2e-test-key', costPer1kPromptTokens: 0.00025, costPer1kCompletionTokens: 0.00085 } const createRes = await request.post(`${API_BASE}/api/admin/endpoints`, { data: newModel }) expect(createRes.status()).toBe(200) const created = await createRes.json() expect(created.modelId).toBe(newModel.modelId) console.log('✓ Dynamic Model Endpoint added:', created.modelId) const listRes = await request.get(`${API_BASE}/api/admin/endpoints`) expect(listRes.status()).toBe(200) const list = await listRes.json() expect(list.some((m: any) => m.modelId === newModel.modelId)).toBe(true) }) test('4. AI Generation & Usage Cost Calculation', async ({ request }) => { // Login to get token const loginRes = await request.post(`${API_BASE}/api/auth/login`, { data: { email: testEmail, password: testPassword } }) const loginData = await loginRes.json() const token = loginData.token // Unauthenticated request MUST fail (401) const unauthRes = await request.post(`${API_BASE}/api/llm/generate`, { data: { prompt: 'Test' } }) expect(unauthRes.status()).toBe(401) console.log('✓ Mandatory Login Guard verified: Unauthenticated request rejected (401)') // Authenticated request const genRes = await request.post(`${API_BASE}/api/llm/generate`, { headers: { Authorization: `Bearer ${token}` }, data: { prompt: 'Self-verification test prompt for D3RO Voice E2E', model: 'd3ro-gpt4o-mini' } }) expect(genRes.status()).toBe(200) const genData = await genRes.json() expect(genData).toHaveProperty('text') expect(genData).toHaveProperty('cost') expect(genData.cost).toBeGreaterThan(0) console.log('✓ AI Generation & Cost Calculation verified:', genData) }) test('5. BackOffice Usage & Cost Analytics Report', async ({ request }) => { const reportRes = await request.get(`${API_BASE}/api/admin/usage`) expect(reportRes.status()).toBe(200) const report = await reportRes.json() expect(report).toHaveProperty('totalRequests') expect(report).toHaveProperty('totalCost') expect(report.userSummaries.length).toBeGreaterThan(0) console.log('✓ BackOffice Usage & Cost Analytics verified:', report) }) test('6. BackOffice Web SPA Page Loading', async ({ page }) => { await page.goto(`${API_BASE}/admin/index.html`) await expect(page.locator('text=D3RO VOICE')).toBeVisible() await expect(page.locator('text=백엔드 서버 대시보드')).toBeVisible() console.log('✓ BackOffice Admin SPA UI loaded successfully.') }) })