test(stammbaum): E2E spec + extend person load mock
- frontend/e2e/stammbaum.spec.ts covers four journeys:
1) /briefwechsel still resolves with a 2xx after the nav swap.
2) /stammbaum shows the page heading.
3) /stammbaum renders either the empty state (with the Personenliste
link) or at least one node[role=button] in the SVG.
4) The person edit card surfaces the year-range error when Bis < Von.
- persons/[id]/page.server.spec.ts gains two extra mockResolvedValueOnce
entries per scenario to match the new relationships +
inferred-relationships GETs that the page load now performs.
Refs #358.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
57
frontend/e2e/stammbaum.spec.ts
Normal file
57
frontend/e2e/stammbaum.spec.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Stammbaum — issue #358', () => {
|
||||
test('nav swap: /briefwechsel still renders without 404', async ({ page }) => {
|
||||
// Plan journey 4: the /briefwechsel route must stay intact even though the
|
||||
// AppNav now points at /stammbaum.
|
||||
const response = await page.goto('/briefwechsel');
|
||||
expect(response?.status()).toBeLessThan(400);
|
||||
await expect(page).toHaveURL(/\/briefwechsel/);
|
||||
});
|
||||
|
||||
test('/stammbaum renders the page heading', async ({ page }) => {
|
||||
await page.goto('/stammbaum');
|
||||
await expect(page.getByRole('heading', { name: 'Stammbaum' })).toBeVisible();
|
||||
});
|
||||
|
||||
test('/stammbaum either shows an empty state or at least one node', async ({ page }) => {
|
||||
// Plan journey 3 (empty branch) and journey 1 (populated branch) covered jointly:
|
||||
// the test passes whenever the page renders one of the two coherent states.
|
||||
await page.goto('/stammbaum');
|
||||
const empty = page.getByRole('heading', { name: 'Noch keine Familienmitglieder' });
|
||||
const anyNode = page.locator('svg[role="img"][aria-label="Stammbaum"] g[role="button"]');
|
||||
await expect(async () => {
|
||||
const emptyVisible = await empty.isVisible().catch(() => false);
|
||||
const nodeCount = await anyNode.count();
|
||||
expect(emptyVisible || nodeCount > 0).toBe(true);
|
||||
}).toPass();
|
||||
|
||||
if (await empty.isVisible().catch(() => false)) {
|
||||
await expect(page.getByRole('link', { name: /Zur Personenliste/ })).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('person edit Stammbaum card surfaces the year-range error', async ({ page }) => {
|
||||
// Plan task 36: Bis < Von triggers the inline error and keeps the form unsubmitted.
|
||||
// We pick the first person, open the edit page, expand the add-rel form, and
|
||||
// inspect the validation message bound to the Bis field.
|
||||
await page.goto('/persons');
|
||||
const firstPerson = page.locator('a[href^="/persons/"]').first();
|
||||
await firstPerson.click();
|
||||
await expect(page).toHaveURL(/\/persons\/[^/]+/);
|
||||
await page.goto(page.url() + '/edit');
|
||||
|
||||
// Open the add-rel form
|
||||
const addBtn = page.getByRole('button', { name: /Beziehung hinzufügen/i });
|
||||
await addBtn.click();
|
||||
|
||||
// Enter Von 1935, Bis 1920 → expect the year-range error
|
||||
const fromInput = page.locator('input[name="fromYear"]');
|
||||
const toInput = page.locator('input[name="toYear"]');
|
||||
await fromInput.fill('1935');
|
||||
await toInput.fill('1920');
|
||||
|
||||
await expect(page.locator('#add-rel-year-error')).toBeVisible();
|
||||
await expect(page.locator('#add-rel-year-error')).toContainText(/Bis.*Von|nicht vor/i);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user