const { test, expect } = require('@playwright/test'); const { loginViaForm, clickBottomNav } = require('./helpers'); test.describe('Login-Flow', () => { test.use({ storageState: { cookies: [], origins: [] } }); test('1. Login funktioniert', async ({ page }) => { await loginViaForm(page); await page.screenshot({ path: 'screenshots/01-nach-login.png' }); console.log('Login erfolgreich'); }); }); test('2. Dashboard laedt ohne Fehler', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('networkidle'); await expect(page.locator('.spinner')).toHaveCount(0, { timeout: 10000 }); await page.screenshot({ path: 'screenshots/02-dashboard.png' }); console.log('Dashboard OK'); }); test('3. Erfassen erreichbar', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('networkidle'); await clickBottomNav(page, 'Erfassen'); await page.waitForLoadState('networkidle'); await expect(page).toHaveURL(/\/capture/); await page.screenshot({ path: 'screenshots/03-erfassung.png' }); console.log('Erfassen OK'); }); test('4. Analyse erreichbar', async ({ page }) => { await page.goto('/'); await page.waitForLoadState('networkidle'); await clickBottomNav(page, 'Analyse'); await page.waitForLoadState('networkidle'); await expect(page).toHaveURL(/\/analysis/); await page.screenshot({ path: 'screenshots/04-analyse.png' }); console.log('Analyse OK'); }); test('5. Keine kritischen Console-Fehler', async ({ page }) => { const errors = []; page.on('console', (msg) => { if (msg.type() === 'error') errors.push(msg.text()); }); await page.goto('/'); await page.waitForLoadState('networkidle'); const kritisch = errors.filter( (e) => !e.includes('favicon') && !e.includes('sourceMap') && !e.includes('404') ); if (kritisch.length > 0) { console.log('Console-Fehler:', kritisch.join(', ')); } else { console.log('Keine kritischen Console-Fehler'); } }); test('FEATURE: Ernährung — Einzelerfassung, Import-Policy-Hinweis, Zuordnen', async ({ page }) => { await page.goto('/nutrition'); await page.waitForLoadState('networkidle'); await expect(page.getByRole('button', { name: /Einzelerfassung/i })).toBeVisible(); await page.getByRole('button', { name: /Import/i }).click(); await expect(page.locator('.card').filter({ hasText: 'FDDB CSV Import' })).toBeVisible(); await expect(page.getByText(/Vorhandene Tagesmakros überschreiben/)).toBeVisible(); await page.getByRole('button', { name: /Zuordnen/i }).click(); await expect(page.getByText(/Lebensmittel zuordnen/)).toBeVisible(); await expect(page.getByRole('button', { name: /FDDB-Listen/ })).toBeVisible(); }); test('FEATURE: Settings — Ernährungs-Import-Policy', async ({ page }) => { await page.goto('/settings'); await page.waitForLoadState('networkidle'); await expect(page.getByText('Ernährungs-Import')).toBeVisible(); await expect(page.locator('select').filter({ has: page.locator('option[value="prompt"]') })).toBeVisible(); }); test('API: nutrition unmapped + marks erreichbar', async ({ page }) => { await page.goto('/nutrition'); await page.waitForLoadState('networkidle'); const token = await page.evaluate(() => localStorage.getItem('bodytrack_token')); expect(token).toBeTruthy(); const headers = { 'X-Auth-Token': token }; const unmapped = await page.request.get('/api/nutrition/unmapped', { headers }); expect(unmapped.ok()).toBeTruthy(); const marks = await page.request.get('/api/nutrition/marks', { headers }); expect(marks.ok()).toBeTruthy(); const foods = await page.request.get('/api/bls/foods?q=hafer', { headers }); expect(foods.ok()).toBeTruthy(); });