Neues FilterPanel-Muster (src/components/FilterPanel.tsx + filterPanel.css): - Mobil (<768px): Suchfeld immer sichtbar; alle weiteren Filter hinter einem 'Filter (N)'-Button eingeklappt (Badge = Anzahl aktiver Nicht-Default-Filter). Tippen öffnet/schließt den Drawer. 'Filter zurücksetzen' im Drawer. - Desktop (>=768px): Toggle versteckt, Drawer als display:contents → alle Controls inline in der bestehenden .filters-Flexzeile, wie bisher. Auf GerbilsPage, WuerfeListPage und AnfragenPage ausgerollt. BeckenPage/KontaktePage nur ein Suchfeld → kein Panel nötig. e2e: filter-panel.spec.ts (8 Tests, phone+desktop); bestand/tiere/anfragen-Specs erhalten openFilterPanel-Aufruf vor Drawer-Controls; fixtures.ts +openFilterPanel(). Vitest 78 / e2e 102 grün. Mobil-Pass (390px, Durchsicht): Hauptproblem behoben. Beobachtete Restpunkte für god (nicht selbst gefixed): - .genotype-table in Genetik/Probeverpaarung: Genotyp-Strings können eng werden - Stammbaum (react-d3-tree SVG): kein explizites mobile Viewport-Handling - BreedingResultView Genotyp-Detail-Tabelle: ggf. horizontal scrollbar-los Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
/**
|
||
* UX-MOBILE-1: FilterPanel — einklappbare Filter auf Smartphone, inline auf Desktop.
|
||
*
|
||
* Telefon (390px): Filter-Button sichtbar, Drawer eingeklappt; Tippen öffnet/schliesst.
|
||
* Desktop (1280px): Alle Controls direkt sichtbar, kein Toggle-Button.
|
||
*/
|
||
import { de, expect, gotoSection, skipUnlessMock, test } from './fixtures'
|
||
|
||
const t = de.pages.gerbils
|
||
|
||
test.describe('FilterPanel – Rennmäuse-Liste', () => {
|
||
test('Phone: Filter-Drawer standardmäßig eingeklappt, Toggle-Button sichtbar', async ({
|
||
page,
|
||
}, testInfo) => {
|
||
skipUnlessMock()
|
||
if (testInfo.project.name !== 'phone') return
|
||
|
||
await gotoSection(page, de.nav.gerbils)
|
||
await expect(page.getByRole('heading', { name: t.title, exact: true })).toBeVisible()
|
||
|
||
// Toggle-Button sichtbar.
|
||
const toggle = page.locator('.filter-panel__toggle')
|
||
await expect(toggle).toBeVisible()
|
||
|
||
// Status-Beschriftung im Drawer ist noch verborgen.
|
||
await expect(page.getByText(t.filters.status, { exact: true }).first()).not.toBeVisible()
|
||
})
|
||
|
||
test('Phone: Toggle öffnet und schließt den Filter-Drawer', async ({
|
||
page,
|
||
}, testInfo) => {
|
||
skipUnlessMock()
|
||
if (testInfo.project.name !== 'phone') return
|
||
|
||
await gotoSection(page, de.nav.gerbils)
|
||
const toggle = page.locator('.filter-panel__toggle')
|
||
|
||
// Öffnen → Status-Feld wird sichtbar.
|
||
await toggle.click()
|
||
await expect(page.getByText(t.filters.status, { exact: true }).first()).toBeVisible()
|
||
|
||
// Schließen → wieder verborgen.
|
||
await toggle.click()
|
||
await expect(page.getByText(t.filters.status, { exact: true }).first()).not.toBeVisible()
|
||
})
|
||
|
||
test('Phone: Badge zählt aktive Filter korrekt', async ({
|
||
page,
|
||
}, testInfo) => {
|
||
skipUnlessMock()
|
||
if (testInfo.project.name !== 'phone') return
|
||
|
||
await gotoSection(page, de.nav.gerbils)
|
||
const toggle = page.locator('.filter-panel__toggle')
|
||
|
||
// Initial: Status='Active' ist Default → Badge zeigt kein „(N)".
|
||
await expect(toggle).toHaveText('Filter')
|
||
|
||
// Filter-Drawer öffnen und Geschlecht setzen → 1 aktiver Filter.
|
||
await toggle.click()
|
||
await page.locator('.filter-panel__drawer select').nth(1).selectOption('male')
|
||
await expect(toggle).toHaveText('Filter (1)')
|
||
|
||
// Zurücksetzen → Badge weg.
|
||
await page.getByRole('button', { name: de.filterPanel.resetButton }).click()
|
||
await expect(toggle).toHaveText('Filter')
|
||
})
|
||
|
||
test('Desktop: Toggle-Button nicht sichtbar, alle Controls inline', async ({
|
||
page,
|
||
}, testInfo) => {
|
||
skipUnlessMock()
|
||
if (testInfo.project.name !== 'desktop') return
|
||
|
||
await gotoSection(page, de.nav.gerbils)
|
||
await expect(page.getByRole('heading', { name: t.title, exact: true })).toBeVisible()
|
||
|
||
// Kein Toggle-Button auf Desktop (display:none via Media Query).
|
||
const toggle = page.locator('.filter-panel__toggle')
|
||
await expect(toggle).toBeHidden()
|
||
|
||
// Status-Beschriftung direkt sichtbar.
|
||
await expect(page.getByText(t.filters.status, { exact: true }).first()).toBeVisible()
|
||
})
|
||
})
|