- StammbaumPage: PedigreeCard-Name + PrintCell-Name + beide titleFor()-Aufrufe → g.name || nameless
- VertragWizardPage: wizard-pick__name + join(', ')-Tierliste → g.name || nameless
- WurfFormPage: fatherName/motherName in Prefill (nameById.get || nameless) + Picker-Auswahl (g.name || nameless)
e2e: neuer Test stammbaum.spec — namenloser Ahne zeigt Platzhalter in Karte + Titel
Gate: vitest 82/82, e2e 148/148, tsc clean
65 lines
2.9 KiB
TypeScript
65 lines
2.9 KiB
TypeScript
/** QA-1: Stammbaum (FEAT-4) — interaktiver Viewer, Re-Root, Druckansicht. */
|
|
import { de, expect, skipUnlessMock, test } from './fixtures'
|
|
|
|
const t = de.pages.stammbaum
|
|
|
|
test('Viewer rendert die Ahnen-Karten und re-rootet per Tipp aufs Elterntier', async ({ page }) => {
|
|
skipUnlessMock()
|
|
await page.goto('/rennmaeuse/kruemel/stammbaum')
|
|
await expect(page.locator('.pedigree-card').first()).toBeVisible()
|
|
await expect(page.getByRole('heading', { name: t.titleFor('Krümel') })).toBeVisible()
|
|
|
|
// Erst die Ansicht einpassen, damit alle Karten im SVG-Viewport liegen
|
|
// (sonst tippt der Klick auf dem Laptop ins Leere).
|
|
const fit = page.getByRole('button', { name: t.zoomFit })
|
|
if (await fit.isVisible()) await fit.click()
|
|
|
|
// Tipp auf den Vater -> Stammbaum wurzelt neu auf Fridolin.
|
|
// (force: die d3-Baum-Animation bewegt die Karten noch eine Weile —
|
|
// Playwrights Stabilitäts-Check würde sonst dauerhaft warten.)
|
|
await page.waitForTimeout(900)
|
|
await page
|
|
.locator('.pedigree-card:not(.pedigree-card--root):not(.pedigree-card--unknown)')
|
|
.filter({ hasText: 'Fridolin' })
|
|
.first()
|
|
.click({ force: true })
|
|
await page.waitForURL('**/rennmaeuse/fridolin/stammbaum')
|
|
await expect(page.getByRole('heading', { name: t.titleFor('Fridolin') })).toBeVisible()
|
|
})
|
|
|
|
test('Inzuchtkoeffizient wird angezeigt', async ({ page }) => {
|
|
skipUnlessMock()
|
|
await page.goto('/rennmaeuse/kruemel/stammbaum')
|
|
const inzucht = page.locator('.stammbaum-inzucht')
|
|
await expect(inzucht).toBeVisible()
|
|
await expect(inzucht).toContainText(t.inbreeding.label)
|
|
// 0.0625 -> de-DE mit max. 1 Nachkommastelle -> "6,3 %"
|
|
await expect(inzucht).toContainText('6,3')
|
|
})
|
|
|
|
test('Druckansicht (Ahnentafel) erscheint im Print-Medium', async ({ page }) => {
|
|
skipUnlessMock()
|
|
await page.goto('/rennmaeuse/kruemel/stammbaum')
|
|
await expect(page.locator('.pedigree-card').first()).toBeVisible()
|
|
|
|
await page.emulateMedia({ media: 'print' })
|
|
// Spaltenüberschriften der Ahnentafel + Erstellt-am-Zeile
|
|
await expect(page.getByText(t.printView.generations[1], { exact: true })).toBeVisible()
|
|
await expect(page.getByText(new RegExp(t.printView.createdOn))).toBeVisible()
|
|
await page.emulateMedia({ media: 'screen' })
|
|
})
|
|
|
|
test('unbekanntes Tier zeigt den deutschen Nicht-gefunden-Zustand', async ({ page }) => {
|
|
await page.goto('/rennmaeuse/gibt-es-nicht/stammbaum')
|
|
await expect(page.getByText(t.notFound).or(page.getByText(de.api.errors.notFound))).toBeVisible()
|
|
})
|
|
|
|
test('Namenloser Ahne zeigt Platzhalter in der Stammbaum-Karte (UI-POLISH-2)', async ({ page }) => {
|
|
skipUnlessMock()
|
|
await page.goto('/rennmaeuse/nameless-stub/stammbaum')
|
|
// Titel zeigt '(ohne Namen)'
|
|
await expect(page.getByRole('heading', { name: t.titleFor(de.pages.gerbils.nameless) })).toBeVisible()
|
|
// Karte selbst zeigt '(ohne Namen)' statt leer
|
|
await expect(page.locator('.pedigree-card__nametext')).toHaveText(de.pages.gerbils.nameless)
|
|
})
|