diff --git a/app/playwright.config.ts b/app/playwright.config.ts new file mode 100644 index 0000000..676a7b3 --- /dev/null +++ b/app/playwright.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + testDir: 'tests/e2e', + use: { baseURL: 'http://localhost:5173' }, + webServer: { + command: 'npm run dev', + port: 5173, + reuseExistingServer: true, + timeout: 120_000 + }, + timeout: 60_000 +}); diff --git a/app/src/lib/components/PostView.svelte b/app/src/lib/components/PostView.svelte index 0b06b2a..f838d01 100644 --- a/app/src/lib/components/PostView.svelte +++ b/app/src/lib/components/PostView.svelte @@ -1,6 +1,10 @@ + +{#if reactions.length > 0} +
+ {#each reactions as r} + + {displayChar(r.content)} + {r.count} + + {/each} +
+{/if} + + diff --git a/app/src/lib/components/ReplyComposer.svelte b/app/src/lib/components/ReplyComposer.svelte new file mode 100644 index 0000000..49918b2 --- /dev/null +++ b/app/src/lib/components/ReplyComposer.svelte @@ -0,0 +1,148 @@ + + +
+ {#if !nip07} +

+ Um zu kommentieren, benötigst du eine Nostr-Extension + (Alby, + nos2x), oder + kommentiere direkt in einem Nostr-Client. +

+ {:else} + +
+ +
+ {#if error}

{error}

{/if} + {#if info}

{info}

{/if} + {/if} +
+ + diff --git a/app/src/lib/components/ReplyItem.svelte b/app/src/lib/components/ReplyItem.svelte new file mode 100644 index 0000000..63d746f --- /dev/null +++ b/app/src/lib/components/ReplyItem.svelte @@ -0,0 +1,44 @@ + + +
  • +
    + {authorNpub} + · + {date} +
    +
    {event.content}
    +
  • + + diff --git a/app/src/lib/components/ReplyList.svelte b/app/src/lib/components/ReplyList.svelte new file mode 100644 index 0000000..3bff962 --- /dev/null +++ b/app/src/lib/components/ReplyList.svelte @@ -0,0 +1,68 @@ + + +
    +

    Kommentare ({merged.length})

    + {#if loading} +

    Lade Kommentare …

    + {:else if merged.length === 0} +

    Noch keine Kommentare.

    + {:else} + + {/if} +
    + + diff --git a/app/test-results/.last-run.json b/app/test-results/.last-run.json new file mode 100644 index 0000000..cbcc1fb --- /dev/null +++ b/app/test-results/.last-run.json @@ -0,0 +1,4 @@ +{ + "status": "passed", + "failedTests": [] +} \ No newline at end of file diff --git a/app/tests/e2e/home.test.ts b/app/tests/e2e/home.test.ts new file mode 100644 index 0000000..443ed31 --- /dev/null +++ b/app/tests/e2e/home.test.ts @@ -0,0 +1,8 @@ +import { expect, test } from '@playwright/test'; + +test('Home zeigt Profil und mindestens einen Post', async ({ page }) => { + await page.goto('/'); + await expect(page.getByRole('heading', { level: 1, name: /Beiträge/ })).toBeVisible(); + await expect(page.locator('.profile .name')).toBeVisible({ timeout: 15_000 }); + await expect(page.locator('a.card').first()).toBeVisible({ timeout: 15_000 }); +}); diff --git a/app/tests/e2e/post.test.ts b/app/tests/e2e/post.test.ts new file mode 100644 index 0000000..1f32c9b --- /dev/null +++ b/app/tests/e2e/post.test.ts @@ -0,0 +1,16 @@ +import { expect, test } from '@playwright/test'; + +test('Einzelpost rendert Titel und Markdown-Body', async ({ page }) => { + await page.goto('/dezentrale-oep-oer/'); + // Titel steht einmal als .post-title (H1 außerhalb des Artikels), + // und nochmal im Markdown-Body des Events — wir prüfen den ersten. + await expect(page.locator('h1.post-title')).toBeVisible({ timeout: 15_000 }); + await expect(page.locator('h1.post-title')).toContainText('Gemeinsam die Bildungszukunft'); + await expect(page.locator('article')).toContainText('Open Educational'); +}); + +test('Legacy-URL wird auf kurze Form umgeleitet', async ({ page }) => { + await page.goto('/2025/03/04/dezentrale-oep-oer.html/'); + await expect(page).toHaveURL(/\/dezentrale-oep-oer\/$/); + await expect(page.locator('h1.post-title')).toBeVisible({ timeout: 15_000 }); +});