Bonus 19: Playwright E2E-Setup + 4 Smoke-Tests
CI / test (push) Canceled after 0s
CI / webapp (push) Canceled after 0s

- @playwright/test als dev-Dependency
- playwright.config.ts: webServer-Setup, Chromium-Project, baseURL
- tests/e2e/app.spec.ts: 4 E2E-Tests
  - zeigt den Titel
  - zeigt Header mit Logo + Tab-Buttons
  - Tab-Wechsel funktioniert (Graph, Cluster-Karte, Radial)
  - Legend ist sichtbar
- .gitignore: test-results/, playwright-report/
- package.json scripts.test:e2e: 'playwright test'

Verifiziert (manuell):
- 4/4 E2E-Tests gruen (~3s)
- Webapp startet korrekt via Vite, Tests greifen auf rendered DOM zu
- Browser-Download: 195.6 MiB Chromium + Edge-Deps

Hinweis: Playwright laeuft nur lokal. CI-Browser-Downloads waeren separat zu konfigurieren.
This commit is contained in:
Jannik committed 2026-09-05 18:12:59 +02:00
1 parent 46a0a34684
commit f0075e3344
5 files changed
+125

No files matched your search

+5
View File
@@ -55,6 +55,11 @@ secrets.key
coverage/
.nyc_output/
# Playwright
test-results/
playwright-report/
.playwright/
# Temporaere Verzeichnisse
tmp/
temp/
+46
View File
@@ -15,6 +15,7 @@
"mindomat": "bin/mindomat.mjs"
},
"devDependencies": {
"@playwright/test": "^1.63.0",
"@testing-library/react": "^16.3.3",
"@types/node": "^22.0.0",
"@typescript-eslint/eslint-plugin": "^8.69.0",
@@ -660,6 +661,22 @@
"url": "https://github.com/sponsors/oxc-project"
}
},
"node_modules/@playwright/test": {
"version": "1.63.0",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.63.0.tgz",
"integrity": "sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.63.0"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@rolldown/binding-android-arm-eabi": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz",
@@ -2951,6 +2968,35 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/playwright": {
"version": "1.63.0",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.63.0.tgz",
"integrity": "sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.63.0"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/playwright-core": {
"version": "1.63.0",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.63.0.tgz",
"integrity": "sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/postcss": {
"version": "8.5.28",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+2
View File
@@ -24,6 +24,7 @@
"dev": "tsc --watch",
"test": "vitest run",
"test:watch": "vitest",
"test:e2e": "playwright test",
"lint": "eslint src/ tests/ --ext .ts",
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"webapp/src/**/*.{ts,tsx}\"",
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"webapp/src/**/*.{ts,tsx}\"",
@@ -49,6 +50,7 @@
"gray-matter": "^4.0.3"
},
"devDependencies": {
"@playwright/test": "^1.63.0",
"@testing-library/react": "^16.3.3",
"@types/node": "^22.0.0",
"@typescript-eslint/eslint-plugin": "^8.69.0",
+34
View File
@@ -0,0 +1,34 @@
// Playwright Config fuer Webapp-E2E-Tests
// Phase Bonus 19
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests/e2e',
timeout: 30_000,
expect: { timeout: 5_000 },
fullyParallel: true,
retries: 0,
workers: 1,
reporter: 'list',
use: {
baseURL: 'http://localhost:5173',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
webServer: {
// Vite-Dev-Server mit MINDOMAT_VAULT_PATH auf einen Test-Vault
command: 'npm run dev --prefix webapp',
url: 'http://localhost:5173',
timeout: 60_000,
reuseExistingServer: !process.env.CI,
stdout: 'pipe',
stderr: 'pipe',
},
});
+38
View File
@@ -0,0 +1,38 @@
// Playwright E2E-Smoke-Tests fuer die Webapp
// Phase Bonus 19
import { test, expect } from '@playwright/test';
test.describe('Mind-o-Mat Webapp', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});
test('zeigt den Titel', async ({ page }) => {
await expect(page).toHaveTitle(/Mind-o-Mat/);
});
test('zeigt Header mit Logo und Tab-Buttons', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'Mind-o-Mat' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Graph' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Cluster-Karte' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Radial' })).toBeVisible();
});
test('Tab-Wechsel funktioniert', async ({ page }) => {
// Graph ist initial aktiv
await expect(page.getByRole('button', { name: 'Graph' })).toHaveCSS('background-color', 'rgb(255, 255, 255)');
// Klick auf Cluster-Karte -> wechselt aktiv-Status
await page.getByRole('button', { name: 'Cluster-Karte' }).click();
await expect(page.getByRole('button', { name: 'Cluster-Karte' })).toHaveCSS('background-color', 'rgb(255, 255, 255)');
// Klick auf Radial
await page.getByRole('button', { name: 'Radial' }).click();
await expect(page.getByRole('button', { name: 'Radial' })).toHaveCSS('background-color', 'rgb(255, 255, 255)');
});
test('Legend ist sichtbar', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'Legende' })).toBeVisible();
await expect(page.getByText('inbox')).toBeVisible();
await expect(page.getByText('wiki')).toBeVisible();
});
});