test(timeline): add Playwright e2e + RTM rows for event note (#844)
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3m58s
CI / OCR Service Tests (pull_request) Successful in 25s
CI / Backend Unit Tests (pull_request) Successful in 6m21s
CI / fail2ban Regex (pull_request) Failing after 46s
CI / Semgrep Security Scan (pull_request) Successful in 24s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m10s
SDD Gate / RTM Check (pull_request) Successful in 15s
SDD Gate / Contract Validate (pull_request) Successful in 23s
SDD Gate / Constitution Impact (pull_request) Successful in 20s
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3m58s
CI / OCR Service Tests (pull_request) Successful in 25s
CI / Backend Unit Tests (pull_request) Successful in 6m21s
CI / fail2ban Regex (pull_request) Failing after 46s
CI / Semgrep Security Scan (pull_request) Successful in 24s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m10s
SDD Gate / RTM Check (pull_request) Successful in 15s
SDD Gate / Contract Validate (pull_request) Successful in 23s
SDD Gate / Constitution Impact (pull_request) Successful in 20s
zeitstrahl-note.spec.ts seeds PERSONAL and HISTORICAL events with descriptions via API and asserts the note appears in DOM (REQ-001, REQ-004). RTM rows REQ-001–REQ-008 for #844 all marked Done. Closes #844 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
77
frontend/e2e/zeitstrahl-note.spec.ts
Normal file
77
frontend/e2e/zeitstrahl-note.spec.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { test, expect, type APIRequestContext } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Curator-note display on /zeitstrahl (#844) — validates that a description saved
|
||||
* against a curated timeline event surfaces in the DOM under that event's title.
|
||||
* Covers REQ-001 (description flows from backend) and REQ-004 (rendered below title).
|
||||
*/
|
||||
|
||||
const stamp = () => new Date().toISOString().replace(/[^0-9]/g, '');
|
||||
|
||||
async function createEvent(
|
||||
request: APIRequestContext,
|
||||
type: 'PERSONAL' | 'HISTORICAL',
|
||||
title: string,
|
||||
description: string
|
||||
): Promise<string> {
|
||||
const res = await request.post('/api/timeline/events', {
|
||||
data: {
|
||||
title,
|
||||
type,
|
||||
eventDate: '1918-11-11',
|
||||
precision: 'DAY',
|
||||
description
|
||||
}
|
||||
});
|
||||
if (!res.ok()) throw new Error(`create event failed: ${res.status()} ${await res.text()}`);
|
||||
return (await res.json()).id as string;
|
||||
}
|
||||
|
||||
async function deleteEvent(request: APIRequestContext, id: string): Promise<void> {
|
||||
await request.delete(`/api/timeline/events/${id}`);
|
||||
}
|
||||
|
||||
test.describe('Zeitstrahl event note (#844)', () => {
|
||||
let personalEventId: string;
|
||||
let historicalEventId: string;
|
||||
const personalTitle = `E2E Persönlich ${stamp()}`;
|
||||
const historicalTitle = `E2E Historisch ${stamp()}`;
|
||||
const personalNote = 'Persönliche Notiz für diesen Moment.';
|
||||
const historicalNote = 'Historischer Kontext für dieses Ereignis.';
|
||||
|
||||
test.beforeAll(async ({ request }) => {
|
||||
personalEventId = await createEvent(request, 'PERSONAL', personalTitle, personalNote);
|
||||
historicalEventId = await createEvent(request, 'HISTORICAL', historicalTitle, historicalNote);
|
||||
});
|
||||
|
||||
test.afterAll(async ({ request }) => {
|
||||
if (personalEventId) await deleteEvent(request, personalEventId);
|
||||
if (historicalEventId) await deleteEvent(request, historicalEventId);
|
||||
});
|
||||
|
||||
test('PERSONAL curated event note appears below its title on /zeitstrahl (REQ-001, REQ-004)', async ({
|
||||
page
|
||||
}) => {
|
||||
await page.goto('/zeitstrahl');
|
||||
|
||||
const personalEntry = page.locator('li').filter({ hasText: personalTitle }).first();
|
||||
await expect(personalEntry).toBeVisible({ timeout: 10000 });
|
||||
|
||||
const note = personalEntry.locator('[data-testid="event-note"]');
|
||||
await expect(note).toBeVisible();
|
||||
await expect(note).toContainText(personalNote);
|
||||
});
|
||||
|
||||
test('HISTORICAL curated event note appears below its title on /zeitstrahl (REQ-001, REQ-004)', async ({
|
||||
page
|
||||
}) => {
|
||||
await page.goto('/zeitstrahl');
|
||||
|
||||
const historicalEntry = page.locator('li').filter({ hasText: historicalTitle }).first();
|
||||
await expect(historicalEntry).toBeVisible({ timeout: 10000 });
|
||||
|
||||
const note = historicalEntry.locator('[data-testid="event-note"]');
|
||||
await expect(note).toBeVisible();
|
||||
await expect(note).toContainText(historicalNote);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user