import { test, expect } from '@playwright/test'; // Test 1: Navigate to first editable (non-finalized) service edit page test('navigate to first editable service edit page', async ({ page }) => { await page.goto('/services'); await page.waitForLoadState('networkidle'); // Find first unfinalized service (one with edit button) const editButton = page.getByTestId('service-list-edit-button').first(); const hasEditableService = await editButton.isVisible().catch(() => false); if (!hasEditableService) { test.skip(); } // Click edit button await editButton.click(); await page.waitForLoadState('networkidle'); // Verify we're on the edit page await expect(page).toHaveURL(/.*services\/\d+\/edit/); // Verify Moderation block is visible const moderationBlock = page.getByTestId('moderation-block'); await expect(moderationBlock).toBeVisible(); }); // Test 2: Moderation block accordion is visible and can be expanded/collapsed test('moderation block accordion is visible and can be expanded/collapsed', async ({ page }) => { await page.goto('/services'); await page.waitForLoadState('networkidle'); // Find first unfinalized service const editButton = page.getByTestId('service-list-edit-button').first(); const hasEditableService = await editButton.isVisible().catch(() => false); if (!hasEditableService) { test.skip(); } await editButton.click(); await page.waitForLoadState('networkidle'); // Find the Moderation block toggle button const blockToggles = page.getByTestId('service-edit-block-toggle'); const moderationToggle = blockToggles.filter({ has: page.locator('text=Moderation') }).first(); const toggleExists = await moderationToggle.isVisible().catch(() => false); if (!toggleExists) { test.skip(); } // Verify toggle button is visible await expect(moderationToggle).toBeVisible(); // Get the Moderation block content container const moderationBlock = page.getByTestId('moderation-block'); // Verify block is initially visible (expanded by default) await expect(moderationBlock).toBeVisible(); // Click toggle to collapse await moderationToggle.click(); await page.waitForTimeout(300); // Wait for transition // Verify block is hidden const isHidden = await moderationBlock.isHidden().catch(() => true); expect(isHidden).toBe(true); // Click toggle again to expand await moderationToggle.click(); await page.waitForTimeout(300); // Wait for transition // Verify block is visible again await expect(moderationBlock).toBeVisible(); }); // Test 3: Upload area is visible with drag-and-drop zone (NO datepicker) test('upload area is visible with drag-and-drop zone', async ({ page }) => { await page.goto('/services'); await page.waitForLoadState('networkidle'); // Find first unfinalized service const editButton = page.getByTestId('service-list-edit-button').first(); const hasEditableService = await editButton.isVisible().catch(() => false); if (!hasEditableService) { test.skip(); } await editButton.click(); await page.waitForLoadState('networkidle'); // Verify Moderation block uploader is visible const uploader = page.getByTestId('moderation-block-uploader'); await expect(uploader).toBeVisible(); // Verify dropzone is visible const dropzone = page.getByTestId('slide-uploader-dropzone'); await expect(dropzone).toBeVisible(); // Verify dropzone contains expected text await expect(dropzone).toContainText('Dateien hier ablegen'); await expect(dropzone).toContainText('oder klicken zum Auswählen'); // Verify NO expire date input (unlike Information block) const expireInput = page.getByTestId('slide-uploader-expire-input'); const expireInputExists = await expireInput.isVisible().catch(() => false); expect(expireInputExists).toBe(false); }); // Test 4: Existing moderation slides display as thumbnails test('existing moderation slides display as thumbnails', async ({ page }) => { await page.goto('/services'); await page.waitForLoadState('networkidle'); // Find first unfinalized service const editButton = page.getByTestId('service-list-edit-button').first(); const hasEditableService = await editButton.isVisible().catch(() => false); if (!hasEditableService) { test.skip(); } await editButton.click(); await page.waitForLoadState('networkidle'); // Verify slide grid is visible const slideGrid = page.getByTestId('moderation-block-grid'); await expect(slideGrid).toBeVisible(); // Check if slides exist const slideThumbnails = page.locator('[data-testid="slide-grid-delete-button"]'); const slideCount = await slideThumbnails.count(); if (slideCount === 0) { // No slides exist - verify empty state message const emptyState = slideGrid.locator('text=Noch keine Folien vorhanden'); await expect(emptyState).toBeVisible(); return; } // Slides exist - verify first thumbnail is visible const firstThumbnail = page.locator('[data-testid="slide-grid-delete-button"]').first(); await expect(firstThumbnail).toBeVisible(); // Verify delete button is visible on hover const deleteButton = firstThumbnail; await expect(deleteButton).toBeVisible(); }); // Test 5: Delete button on moderation slide thumbnail triggers confirmation test('delete button on moderation slide thumbnail triggers confirmation', async ({ page }) => { await page.goto('/services'); await page.waitForLoadState('networkidle'); // Find first unfinalized service const editButton = page.getByTestId('service-list-edit-button').first(); const hasEditableService = await editButton.isVisible().catch(() => false); if (!hasEditableService) { test.skip(); } await editButton.click(); await page.waitForLoadState('networkidle'); // Check if slides exist const slideThumbnails = page.locator('[data-testid="slide-grid-delete-button"]'); const slideCount = await slideThumbnails.count(); if (slideCount === 0) { // No slides exist - skip this test test.skip(); } // Get first delete button const firstDeleteButton = page.getByTestId('slide-grid-delete-button').first(); await expect(firstDeleteButton).toBeVisible(); // Click delete button await firstDeleteButton.click(); await page.waitForTimeout(200); // Verify confirmation dialog appears const confirmDialog = page.locator('text=Folie löschen?'); await expect(confirmDialog).toBeVisible(); // Verify dialog contains expected text await expect(page.locator('text=Möchtest du die Folie')).toBeVisible(); await expect(page.locator('text=wirklich löschen?')).toBeVisible(); // Verify cancel button is visible const cancelButton = page.locator('button:has-text("Abbrechen")').first(); await expect(cancelButton).toBeVisible(); // Click cancel to close dialog without deleting await cancelButton.click(); await page.waitForTimeout(200); // Verify dialog is closed const dialogClosed = await confirmDialog.isHidden().catch(() => true); expect(dialogClosed).toBe(true); });