Katalog, lernendes Mapping ohne KI, optionale Items und Import-Policy. Playwright-Smoke und Issue-Audit um Ernährung/Zuordnen/API ergänzt. Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
3.5 KiB
JavaScript
90 lines
3.5 KiB
JavaScript
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();
|
|
});
|
|
|
|
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();
|
|
});
|