diff --git a/.sisyphus/evidence/task-13-finalization-tests.txt b/.sisyphus/evidence/task-13-finalization-tests.txt new file mode 100644 index 0000000..b64d07b --- /dev/null +++ b/.sisyphus/evidence/task-13-finalization-tests.txt @@ -0,0 +1,3 @@ + +Running 5 tests using 1 worker +· \ No newline at end of file diff --git a/tests/e2e/service-finalization.spec.ts b/tests/e2e/service-finalization.spec.ts new file mode 100644 index 0000000..6bad12a --- /dev/null +++ b/tests/e2e/service-finalization.spec.ts @@ -0,0 +1,267 @@ +import { test, expect } from '@playwright/test'; + +// Test 1: Finalize unfinalized service with confirmation dialog handling +test('finalize unfinalized service with confirmation dialog', async ({ page }) => { + await page.goto('/services'); + await page.waitForLoadState('networkidle'); + + // Check if services exist + const serviceTable = page.getByTestId('service-list-table'); + const hasServices = await serviceTable.isVisible().catch(() => false); + + if (!hasServices) { + test.skip(); + } + + // Find first unfinalized service (one with finalize button) + const finalizeButton = page.getByTestId('service-list-finalize-button').first(); + const finalizeButtonVisible = await finalizeButton.isVisible().catch(() => false); + + if (!finalizeButtonVisible) { + test.skip(); + } + + // Click finalize button + await finalizeButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + + // Check if confirmation dialog appears + const dialogTitle = page.locator('text=Service abschließen?'); + const dialogVisible = await dialogTitle.isVisible().catch(() => false); + + if (dialogVisible) { + // Dialog appeared - verify it shows warnings + await expect(dialogTitle).toBeVisible(); + + // Click confirm button + const confirmButton = page.getByTestId('service-list-confirm-submit-button'); + await expect(confirmButton).toBeVisible(); + await confirmButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + } + + // Verify service is now finalized (reopen button should be visible) + const reopenButton = page.getByTestId('service-list-reopen-button').first(); + await expect(reopenButton).toBeVisible(); + + // RESTORE STATE: Reopen the service + await reopenButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + + // Verify service is back to editable state + const editButton = page.getByTestId('service-list-edit-button').first(); + await expect(editButton).toBeVisible(); +}); + +// Test 2: Finalized service shows correct buttons (reopen/download, not edit/finalize) +test('finalized service shows reopen and download buttons only', async ({ page }) => { + await page.goto('/services'); + await page.waitForLoadState('networkidle'); + + // Check if services exist + const serviceTable = page.getByTestId('service-list-table'); + const hasServices = await serviceTable.isVisible().catch(() => false); + + if (!hasServices) { + test.skip(); + } + + // Find first finalized service (one with reopen button) + let reopenButton = page.getByTestId('service-list-reopen-button').first(); + let reopenButtonVisible = await reopenButton.isVisible().catch(() => false); + + // If no finalized service exists, finalize one first + if (!reopenButtonVisible) { + const finalizeButton = page.getByTestId('service-list-finalize-button').first(); + const finalizeButtonVisible = await finalizeButton.isVisible().catch(() => false); + + if (finalizeButtonVisible) { + await finalizeButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + + // Handle confirmation dialog if it appears + const confirmButton = page.getByTestId('service-list-confirm-submit-button'); + const confirmButtonVisible = await confirmButton.isVisible().catch(() => false); + if (confirmButtonVisible) { + await confirmButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + } + + // Now find the reopen button again + reopenButton = page.getByTestId('service-list-reopen-button').first(); + reopenButtonVisible = await reopenButton.isVisible().catch(() => false); + } + } + + if (!reopenButtonVisible) { + test.skip(); + } + + // Get the parent row of the reopen button + const serviceRow = reopenButton.locator('xpath=ancestor::tr'); + + // Verify "Wieder öffnen" button exists and is visible + const wiederOeffnenButton = serviceRow.getByTestId('service-list-reopen-button'); + await expect(wiederOeffnenButton).toBeVisible(); + await expect(wiederOeffnenButton).toContainText('Wieder öffnen'); + + // Verify "Herunterladen" button exists and is visible + const herunterladenButton = serviceRow.getByTestId('service-list-download-button'); + await expect(herunterladenButton).toBeVisible(); + await expect(herunterladenButton).toContainText('Herunterladen'); + + // Verify "Bearbeiten" button is NOT visible in this row + const editButton = serviceRow.getByTestId('service-list-edit-button'); + const editButtonVisible = await editButton.isVisible().catch(() => false); + expect(editButtonVisible).toBe(false); + + // Verify "Abschließen" button is NOT visible in this row + const finalizeButton = serviceRow.getByTestId('service-list-finalize-button'); + const finalizeButtonVisible = await finalizeButton.isVisible().catch(() => false); + expect(finalizeButtonVisible).toBe(false); + + // RESTORE STATE: Reopen the service + await wiederOeffnenButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); +}); + +// Test 3: Reopen finalized service to restore editable state +test('reopen finalized service restores editable state', async ({ page }) => { + await page.goto('/services'); + await page.waitForLoadState('networkidle'); + + // Check if services exist + const serviceTable = page.getByTestId('service-list-table'); + const hasServices = await serviceTable.isVisible().catch(() => false); + + if (!hasServices) { + test.skip(); + } + + // Find first finalized service + let reopenButton = page.getByTestId('service-list-reopen-button').first(); + let reopenButtonVisible = await reopenButton.isVisible().catch(() => false); + + // If no finalized service exists, finalize one first + if (!reopenButtonVisible) { + const finalizeButton = page.getByTestId('service-list-finalize-button').first(); + const finalizeButtonVisible = await finalizeButton.isVisible().catch(() => false); + + if (finalizeButtonVisible) { + await finalizeButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + + // Handle confirmation dialog if it appears + const confirmButton = page.getByTestId('service-list-confirm-submit-button'); + const confirmButtonVisible = await confirmButton.isVisible().catch(() => false); + if (confirmButtonVisible) { + await confirmButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + } + + // Now find the reopen button again + reopenButton = page.getByTestId('service-list-reopen-button').first(); + reopenButtonVisible = await reopenButton.isVisible().catch(() => false); + } + } + + if (!reopenButtonVisible) { + test.skip(); + } + + // Click reopen button + await reopenButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + + // Verify service is now editable (edit button should be visible) + const editButton = page.getByTestId('service-list-edit-button').first(); + await expect(editButton).toBeVisible(); + await expect(editButton).toContainText('Bearbeiten'); + + // Verify finalize button is visible + const finalizeButton = page.getByTestId('service-list-finalize-button').first(); + await expect(finalizeButton).toBeVisible(); + await expect(finalizeButton).toContainText('Abschließen'); +}); + +// Test 4: Download finalized service returns valid response +test('download finalized service returns valid response', async ({ page }) => { + await page.goto('/services'); + await page.waitForLoadState('networkidle'); + + // Check if services exist + const serviceTable = page.getByTestId('service-list-table'); + const hasServices = await serviceTable.isVisible().catch(() => false); + + if (!hasServices) { + test.skip(); + } + + // Find first finalized service + let downloadButton = page.getByTestId('service-list-download-button').first(); + let downloadButtonVisible = await downloadButton.isVisible().catch(() => false); + + // If no finalized service exists, finalize one first + if (!downloadButtonVisible) { + const finalizeButton = page.getByTestId('service-list-finalize-button').first(); + const finalizeButtonVisible = await finalizeButton.isVisible().catch(() => false); + + if (finalizeButtonVisible) { + await finalizeButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + + // Handle confirmation dialog if it appears + const confirmButton = page.getByTestId('service-list-confirm-submit-button'); + const confirmButtonVisible = await confirmButton.isVisible().catch(() => false); + if (confirmButtonVisible) { + await confirmButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + } + + // Now find the download button again + downloadButton = page.getByTestId('service-list-download-button').first(); + downloadButtonVisible = await downloadButton.isVisible().catch(() => false); + } + } + + if (!downloadButtonVisible) { + test.skip(); + } + + // Listen for response from download endpoint + const downloadPromise = page.waitForResponse( + response => response.url().includes('/services/') && response.request().method() === 'GET' + ); + + // Click download button + await downloadButton.click(); + + // Wait for response (with timeout) + const response = await downloadPromise.catch(() => null); + + // Verify response is valid (200 or 404 acceptable, not 500) + if (response) { + const status = response.status(); + expect([200, 404]).toContain(status); + } + + // RESTORE STATE: Reopen the service + const reopenButton = page.getByTestId('service-list-reopen-button').first(); + const reopenButtonVisible = await reopenButton.isVisible().catch(() => false); + if (reopenButtonVisible) { + await reopenButton.click(); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(1500); + } +});