Files
kochwas/tests/e2e/remote/wishlist.spec.ts
hsiegeln a7ad159c69
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m42s
test(e2e): Playwright Smoketests gegen kochwas-dev (remote)
Automatisierte End-to-End-Tests gegen ein deployed Environment. Loest
die manuellen MCP-Playwright-Runs ab. 42 Tests in 9 Files:

- homepage: H1, Sektionen, Sort-Tabs, Console-Errors
- search: lokaler Treffer, Web-Fallback, Empty-State, Deep-Link
- profile: Switcher, Auswahl-Persistenz, Favoriten-Section, Guard-Dialog
- recipe-detail: Header, Portionen-Scaling (4->6), Favorit-Toggle,
  Rating-Persistenz ueber Reload, Gekocht-Counter, Wunschliste-Toggle
- comments: eigenen erstellen+loeschen via UI, fremder hat kein Delete
- wishlist: Seite, Sort-Tabs, Badge-Sync, requireProfile-Custom-Message
- preview: Guard ohne ?url=, echte URL parst, unparsbare zeigt error-box
- admin: alle 4 Subrouten + /admin redirect
- api-errors: parsePositiveIntParam (4x Invalid id), validateBody (4x
  Invalid body + issues), 404, Sanity /health /profiles /domains

Architektur:
- Separate playwright.remote.config.ts (getrennt von local preview)
- workers: 1 + afterEach API-Cleanup (rating, favorite, wishlist, comments)
- Hardcoded Recipe-ID 66 + Profile 1/2/3 — stabile Dev-DB-Seeds
- E2E_REMOTE_URL ueberschreibt die Ziel-URL

Ausfuehrung: npm run test:e2e:remote

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 12:14:04 +02:00

44 lines
1.9 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { clearActiveProfile, setActiveProfile, HENDRIK_ID } from './fixtures/profile';
test.describe('Wunschliste-Seite', () => {
test('laedt Header + Sort-Tabs', async ({ page }) => {
await setActiveProfile(page, HENDRIK_ID);
await page.goto('/wishlist');
await expect(page.getByRole('heading', { level: 1, name: 'Wunschliste' })).toBeVisible();
for (const label of ['Meist gewünscht', 'Neueste', 'Älteste']) {
await expect(page.getByRole('tab', { name: label })).toBeVisible();
}
});
test('Badge im Header stimmt mit Anzahl Eintraegen ueberein', async ({ page, request }) => {
await setActiveProfile(page, HENDRIK_ID);
await page.goto('/wishlist');
// Die API zaehlt die Wunschlisten-Rezepte — der Header-Badge sollte
// die gleiche Zahl zeigen.
const res = await request.get('/api/wishlist?sort=popular');
const body = (await res.json()) as { entries: unknown[] };
const expected = body.entries.length;
if (expected === 0) {
// Kein Badge bei Null — der Link hat dann gar keine Zahl.
return;
}
const badge = page.locator('a[href="/wishlist"]').first();
await expect(badge).toContainText(String(expected));
});
test('requireProfile zeigt Custom-Message "um mitzuwuenschen"', async ({ page }) => {
await clearActiveProfile(page);
await page.goto('/wishlist');
// Erster "Ich will das auch"-Button eines beliebigen Eintrags.
// Falls Wunschliste leer ist, ueberspringen.
const btn = page.getByRole('button', { name: /Ich will das auch/i }).first();
const count = await btn.count();
test.skip(count === 0, 'Wunschliste leer — Custom-Message-Test uebersprungen');
await btn.click();
await expect(page.getByText('Kein Profil gewählt')).toBeVisible();
await expect(page.getByText('um mitzuwünschen')).toBeVisible();
});
});