const { test, expect } = require('@playwright/test'); const TEST_EMAIL = process.env.TEST_EMAIL || 'lars@stommer.com'; const TEST_PASSWORD = process.env.TEST_PASSWORD || '12345678'; /** Primärer Submit auf der Login-Seite (nicht den Tab "Login" vs. "Registrieren"). */ async function submitLoginForm(page) { await page.getByRole('button', { name: 'Anmelden' }).click(); } async function login(page) { await page.goto('/'); await page.waitForLoadState('networkidle'); // Warte bis Login-Seite geladen ist await page.waitForSelector('input[type="email"]', { timeout: 10000 }); await page.fill('input[type="email"]', TEST_EMAIL); await page.fill('input[type="password"]', TEST_PASSWORD); await submitLoginForm(page); await page.waitForLoadState('networkidle'); } test('1. Login funktioniert', async ({ page }) => { await page.goto('/'); await page.waitForSelector('input[type="email"]', { timeout: 10000 }); await page.fill('input[type="email"]', TEST_EMAIL); await page.fill('input[type="password"]', TEST_PASSWORD); await submitLoginForm(page); await page.waitForLoadState('networkidle'); // Nach Login soll der Tab "Login" (Moduswahl) verschwinden — nicht der Submit "Anmelden" const loginButton = page.locator('button:has-text("Login")'); await expect(loginButton).toHaveCount(0, { timeout: 10000 }); await page.screenshot({ path: 'screenshots/01-nach-login.png' }); console.log('✓ Login erfolgreich'); }); test('2. Dashboard lädt ohne Fehler', async ({ page }) => { await login(page); // Warte bis Spinner verschwunden await expect(page.locator('.spinner')).toHaveCount(0, { timeout: 10000 }); // Dashboard: h1 „Dashboard“ + Begrüßungstext (nicht mehr „Willkommen bei Shinkan“ als Überschrift) const main = page.locator('.app-main'); await expect(main.getByRole('heading', { level: 1, name: 'Dashboard' })).toBeVisible({ timeout: 5000, }); await expect(main.getByText(/Shinkan unterstützt dich/i)).toBeVisible({ timeout: 5000 }); await page.screenshot({ path: 'screenshots/02-dashboard.png' }); console.log('✓ Dashboard OK'); }); test('3. Navigation zu Übungen', async ({ page }) => { await login(page); // Bei Viewport ≥1024px ist .bottom-nav versteckt — Mobile garantieren wie in playwright.config.js await page.setViewportSize({ width: 390, height: 844 }); // Desktop-Sidebar enthält ebenfalls Übungen – nur Mobile-Bottom-Nav klicken (sichtbarer Link) await page.locator('.bottom-nav a[href="/exercises"]').click(); await page.waitForLoadState('networkidle'); // Prüfe ob Übungen-Seite geladen await expect(page.locator('h1, h2, .page-title')).toContainText(/übungen/i, { timeout: 5000 }); await page.screenshot({ path: 'screenshots/03-uebungen.png' }); console.log('✓ Übungen-Seite erreichbar'); }); test('4. Navigation zu Vereine', async ({ page }) => { await login(page); await page.setViewportSize({ width: 390, height: 844 }); await page.locator('.bottom-nav a[href="/clubs"]').click(); await page.waitForLoadState('networkidle'); // ClubsPage: