import { test, expect } from '@playwright/test'; async function navigateToEditPage(page) { await page.goto('/services'); await page.waitForLoadState('networkidle'); const editButton = page.getByTestId('service-list-edit-button').first(); const hasEditableService = await editButton.isVisible().catch(() => false); if (!hasEditableService) { return false; } await editButton.click(); await page.waitForLoadState('networkidle'); return true; } test.skip('songs block accordion — replaced by agenda view', async () => {}); test('song items visible in agenda or empty state', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const songItems = page.getByTestId('song-agenda-item'); const songCount = await songItems.count(); if (songCount === 0) { const emptyState = page.getByText('Keine Ablauf-Elemente vorhanden'); const hasEmptyState = await emptyState.isVisible().catch(() => false); expect(hasEmptyState).toBe(true); return; } const firstSongItem = songItems.first(); await expect(firstSongItem).toBeVisible(); const songTitle = firstSongItem.getByTestId('song-agenda-title'); await expect(songTitle).toBeVisible(); }); test('song agenda item shows title and ccli info', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const songItems = page.getByTestId('song-agenda-item'); const songCount = await songItems.count(); if (songCount === 0) { test.skip(); } const firstSongItem = songItems.first(); const songTitle = firstSongItem.getByTestId('song-agenda-title'); await expect(songTitle).toBeVisible(); }); test('unmatched songs show request creation button in agenda', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const requestButton = page.getByTestId('song-request-creation').first(); const hasUnmatched = await requestButton.isVisible().catch(() => false); if (!hasUnmatched) { test.skip(); } await expect(requestButton).toBeVisible(); const searchInput = page.getByTestId('song-search-input').first(); await expect(searchInput).toBeVisible(); const assignButton = page.getByTestId('song-assign-button').first(); await expect(assignButton).toBeVisible(); }); test('matched songs show arrangement pill in agenda', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const arrangementPill = page.getByTestId('arrangement-pill').first(); const hasPill = await arrangementPill.isVisible().catch(() => false); if (!hasPill) { test.skip(); } await expect(arrangementPill).toBeVisible(); }); test('arrangement edit button opens arrangement dialog', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const editArrangementBtn = page.getByTestId('song-edit-arrangement').first(); const hasBtn = await editArrangementBtn.isVisible().catch(() => false); if (!hasBtn) { test.skip(); } await editArrangementBtn.click(); await page.waitForTimeout(500); const arrangementDialog = page.getByTestId('arrangement-dialog'); await expect(arrangementDialog).toBeVisible(); const closeBtn = page.getByTestId('arrangement-dialog-close-btn'); await closeBtn.click(); await page.waitForTimeout(300); }); test('arrangement dialog has select, add, clone buttons', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const editArrangementBtn = page.getByTestId('song-edit-arrangement').first(); const hasBtn = await editArrangementBtn.isVisible().catch(() => false); if (!hasBtn) { test.skip(); } await editArrangementBtn.click(); await page.waitForTimeout(500); const arrangementDialog = page.getByTestId('arrangement-dialog'); const dialogVisible = await arrangementDialog.isVisible().catch(() => false); if (!dialogVisible) { test.skip(); } const arrangementSelect = page.getByTestId('arrangement-select').first(); await expect(arrangementSelect).toBeVisible(); const addButton = page.getByTestId('arrangement-new-btn').first(); await expect(addButton).toBeVisible(); const cloneButton = page.getByTestId('arrangement-clone-btn').first(); await expect(cloneButton).toBeVisible(); const closeBtn = page.getByTestId('arrangement-dialog-close-btn'); await closeBtn.click(); await page.waitForTimeout(300); }); test.skip('preview button is present for matched songs — replaced by agenda view', async () => {}); test.skip('download button is present for matched songs — replaced by agenda view', async () => {}); test('translation checkbox toggles if song has translation', async ({ page }) => { const navigated = await navigateToEditPage(page); if (!navigated) { test.skip(); } const translationCheckbox = page.getByTestId('song-translation-checkbox').first(); const hasTranslation = await translationCheckbox.isVisible().catch(() => false); if (!hasTranslation) { test.skip(); } const initialState = await translationCheckbox.isChecked(); await translationCheckbox.click(); await page.waitForTimeout(300); const toggledState = await translationCheckbox.isChecked(); expect(toggledState).not.toBe(initialState); await translationCheckbox.click(); await page.waitForTimeout(300); const restoredState = await translationCheckbox.isChecked(); expect(restoredState).toBe(initialState); });