776149e7d3
Sprint 12 Phase 2: Real integration tests with seed DB - R__seed_test_data.sql (Flyway repeatable, 7 members, strains, batches, docs, board, events) - TestResetController (profile-gated per-test DB reset) - docker-compose.test.yml (self-contained, tmpfs Postgres) - Dockerfile.playwright (v1.60.0, pre-installed deps) - 13 integration spec files, 70+ test cases (@smoke + @full) - seed-constants.ts, selectors.ts, api-client.ts test helpers
129 lines
3.6 KiB
TypeScript
129 lines
3.6 KiB
TypeScript
import { expect, test } from "@playwright/test"
|
||
|
||
import { ApiClient } from "../api-client"
|
||
import { SEED } from "../seed-constants"
|
||
|
||
const apiClient = new ApiClient()
|
||
|
||
test.describe("Calendar Page @full", () => {
|
||
test.beforeEach(async () => {
|
||
await apiClient.login(SEED.admin.email, SEED.admin.password)
|
||
await apiClient.resetDb()
|
||
})
|
||
|
||
test("renders current month", async ({ page }) => {
|
||
await page.goto("/calendar")
|
||
|
||
// Calendar should show current month name
|
||
const now = new Date()
|
||
const monthNames = [
|
||
"Januar",
|
||
"Februar",
|
||
"März",
|
||
"April",
|
||
"Mai",
|
||
"Juni",
|
||
"Juli",
|
||
"August",
|
||
"September",
|
||
"Oktober",
|
||
"November",
|
||
"Dezember",
|
||
]
|
||
const currentMonth = monthNames[now.getMonth()]
|
||
const currentYear = now.getFullYear().toString()
|
||
|
||
await expect(
|
||
page
|
||
.getByText(currentMonth, { exact: false })
|
||
.or(page.getByText(currentYear))
|
||
).toBeVisible()
|
||
})
|
||
|
||
test("seed events are visible", async ({ page }) => {
|
||
await page.goto("/calendar")
|
||
|
||
// There should be an upcoming assembly event (~14 days from now)
|
||
// and a past social event (~30 days ago) — look for event indicators
|
||
await expect(
|
||
page
|
||
.getByText(/versammlung|assembly/i)
|
||
.or(page.locator("[data-testid*='event']").first())
|
||
).toBeVisible()
|
||
})
|
||
|
||
test("month navigation works", async ({ page }) => {
|
||
await page.goto("/calendar")
|
||
|
||
// Find prev/next month buttons
|
||
const nextBtn = page.getByRole("button", { name: /next|vor|nächst|›|>/i })
|
||
const prevBtn = page.getByRole("button", {
|
||
name: /prev|zurück|vorig|‹|</i,
|
||
})
|
||
|
||
// Navigate forward
|
||
if (await nextBtn.isVisible()) {
|
||
await nextBtn.click()
|
||
await page.waitForTimeout(300)
|
||
// Page should still render without error
|
||
await expect(page.locator("body")).toBeVisible()
|
||
}
|
||
|
||
// Navigate backward twice (back to previous month)
|
||
if (await prevBtn.isVisible()) {
|
||
await prevBtn.click()
|
||
await page.waitForTimeout(300)
|
||
await prevBtn.click()
|
||
await page.waitForTimeout(300)
|
||
await expect(page.locator("body")).toBeVisible()
|
||
}
|
||
})
|
||
|
||
test("create event opens dialog with form fields", async ({ page }) => {
|
||
await page.goto("/calendar")
|
||
|
||
const createBtn = page
|
||
.getByRole("button", { name: /erstellen|create|neues event|neu/i })
|
||
.or(page.locator('[data-testid="calendar-create-event"]'))
|
||
|
||
if (await createBtn.isVisible()) {
|
||
await createBtn.click()
|
||
// Dialog should have form fields for event creation
|
||
await expect(
|
||
page.getByRole("dialog").or(page.locator("[role='dialog']"))
|
||
).toBeVisible()
|
||
// Expect title/name field
|
||
await expect(
|
||
page
|
||
.getByLabel(/titel|name|bezeichnung/i)
|
||
.or(page.locator("input[name*='title']"))
|
||
).toBeVisible()
|
||
}
|
||
})
|
||
|
||
test("cancel event button shows confirmation", async ({ page }) => {
|
||
await page.goto("/calendar")
|
||
|
||
// Click on an existing event to open detail
|
||
const eventEl = page.locator("[data-testid*='event']").first()
|
||
|
||
if (await eventEl.isVisible()) {
|
||
await eventEl.click()
|
||
await page.waitForTimeout(300)
|
||
|
||
// Look for cancel/delete button
|
||
const cancelBtn = page.getByRole("button", {
|
||
name: /absagen|löschen|cancel|delete/i,
|
||
})
|
||
|
||
if (await cancelBtn.isVisible()) {
|
||
await cancelBtn.click()
|
||
// Should show confirmation dialog
|
||
await expect(
|
||
page.getByRole("alertdialog").or(page.getByText(/bestätigen|sicher/i))
|
||
).toBeVisible()
|
||
}
|
||
}
|
||
})
|
||
})
|