Files
fotospiel-app/tests/ui/admin/event-admin-dashboard.test.ts
2026-01-15 19:54:04 +01:00

148 lines
6.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Page } from '@playwright/test';
import { test, expectFixture as expect } from '../helpers/test-fixtures';
const futureDate = (daysAhead = 10): string => {
const date = new Date();
date.setDate(date.getDate() + daysAhead);
return date.toISOString().slice(0, 10);
};
async function ensureOnDashboard(page: Page): Promise<void> {
await page.goto('/event-admin/mobile/dashboard');
await page.waitForLoadState('networkidle');
if (page.url().includes('/event-admin/mobile/welcome')) {
const directButton = page.getByRole('button', { name: /Direkt zum Dashboard|Jump to dashboard|Dashboard/i });
if (await directButton.isVisible()) {
await directButton.click();
await page.waitForURL(/\/event-admin\/mobile\/dashboard$/, { timeout: 15_000 });
}
}
}
test.describe('Tenant Admin PWA end-to-end coverage', () => {
test.beforeEach(async ({ tenantAdminCredentials, signInTenantAdmin }) => {
test.skip(!tenantAdminCredentials, 'Provide E2E_TENANT_EMAIL and E2E_TENANT_PASSWORD to run admin tests.');
await signInTenantAdmin();
});
test('dashboard highlights core stats and quick actions', async ({ page }) => {
await ensureOnDashboard(page);
await expect(page.getByText(/Dashboard/i)).toBeVisible();
await expect(page.getByRole('button', { name: /Event erstellen|Create event/i })).toBeVisible();
});
test('event creation flow and detail subsections', async ({ page }) => {
const eventName = `Playwright Event ${Date.now()}`;
const eventDate = futureDate(14);
await page.goto('/event-admin/mobile/events/new');
await page.waitForLoadState('networkidle');
await expect(page.getByText(/Event/i)).toBeVisible();
await page.getByPlaceholder(/Sommerfest|Summer Party/i).fill(eventName);
await page.locator('input[type="datetime-local"]').fill(`${eventDate}T18:00`);
const typeSelect = page.locator('select').first();
await typeSelect.selectOption({ index: 1 });
await page.getByRole('button', { name: /Event erstellen|Create event/i }).click();
await expect(page).toHaveURL(/\/event-admin\/mobile\/events\/[a-z0-9-]+$/, { timeout: 20_000 });
const createdSlug = new URL(page.url()).pathname.split('/').pop() ?? '';
await expect(page.getByText(eventName)).toBeVisible();
await page.goto('/event-admin/mobile/events');
await page.waitForLoadState('networkidle');
await expect(page.getByText(eventName, { exact: false })).toBeVisible();
await page.goto(`/event-admin/mobile/events/${createdSlug}/control-room`);
await expect(page.getByText(/Moderation & Live Show|Moderation & Live-Show/i)).toBeVisible();
await page.goto(`/event-admin/mobile/events/${createdSlug}/members`);
await expect(page.getByText(/Event-Mitglieder|Event members/i)).toBeVisible();
await page.goto(`/event-admin/mobile/events/${createdSlug}/tasks`);
await expect(page.getByText(/Aufgaben & Missionen|Tasks & Checklists/i)).toBeVisible();
});
test('task library allows creating custom tasks', async ({ page }) => {
await page.goto('/event-admin/mobile/tasks');
await page.waitForLoadState('networkidle');
await expect(page.getByText(/Tasks|Aufgaben/i)).toBeVisible();
const taskTitle = `Playwright Task ${Date.now()}`;
const addTaskButton = page.getByRole('button', { name: /Aufgabe hinzufügen|Add task/i }).first();
test.skip((await addTaskButton.count()) === 0, 'No active event available to add tasks.');
await addTaskButton.click();
await page.getByPlaceholder(/Gruppenfoto|Group photo/i).fill(taskTitle);
await page.getByPlaceholder(/Optionale Hinweise|Optional/i).fill('Automatisierter Testfall');
await page.getByRole('button', { name: /Aufgabe speichern|Save task/i }).click();
await expect(page.getByText(taskTitle)).toBeVisible({ timeout: 10_000 });
});
test('supporting sections (billing, settings, profile) load successfully', async ({ page }) => {
await page.goto('/event-admin/mobile/billing');
await page.waitForLoadState('networkidle');
await expect(page.getByText(/Pakete|Billing|Abrechnung/i)).toBeVisible();
await page.goto('/event-admin/mobile/settings');
await page.waitForLoadState('networkidle');
await expect(page.getByText(/Einstellungen|Settings/i)).toBeVisible();
await page.goto('/event-admin/mobile/profile');
await page.waitForLoadState('networkidle');
await expect(page.getByText(/Profil|Profile/i)).toBeVisible();
});
test('wedding event workflow assigns tasks and exposes join token', async ({ page, fetchJoinToken }) => {
const eventName = `Playwright Hochzeit ${Date.now()}`;
const eventDate = futureDate(21);
await page.goto('/event-admin/mobile/events/new');
await page.waitForLoadState('networkidle');
await page.getByPlaceholder(/Sommerfest|Summer Party/i).fill(eventName);
await page.locator('input[type="datetime-local"]').fill(`${eventDate}T12:00`);
const eventTypeCombo = page.locator('select').first();
await eventTypeCombo.selectOption({ index: 1 });
await page.getByRole('button', { name: /Event erstellen|Create event/i }).click();
await page.waitForURL(/\/event-admin\/mobile\/events\/[a-z0-9-]+$/i, { timeout: 20_000 });
const createdSlug = new URL(page.url()).pathname.split('/').pop() ?? '';
await page.goto(`/event-admin/mobile/events/${createdSlug}/tasks`);
await expect(page.getByText(/Aufgaben & Missionen|Tasks & Checklists/i)).toBeVisible();
const librarySection = page
.locator('section')
.filter({ hasText: /Tasks aus Bibliothek hinzufügen|Add tasks/i })
.first();
const availableTaskLabels = librarySection.locator('label');
const availableCount = await availableTaskLabels.count();
test.skip(availableCount === 0, 'No task library entries available to assign');
const firstLabel = availableTaskLabels.first();
const taskTitle = ((await firstLabel.locator('p').first().textContent()) ?? '').trim();
await firstLabel.click();
await page
.getByRole('button', { name: /Ausgewählte Tasks zuweisen|Assign selected tasks/i })
.click();
await expect(
page.locator('section').filter({ hasText: /Zugeordnete Tasks|Assigned tasks/i }).getByText(taskTitle, { exact: false }),
).toBeVisible({ timeout: 15_000 });
const joinToken = await fetchJoinToken({ slug: createdSlug });
expect(joinToken.token).toBeTruthy();
expect(joinToken.join_url).toContain(joinToken.token);
expect(joinToken.qr_svg).toContain('<svg');
});
});