diff --git a/tests/e2e/auth.spec.ts b/tests/e2e/auth.spec.ts new file mode 100644 index 0000000..7714f61 --- /dev/null +++ b/tests/e2e/auth.spec.ts @@ -0,0 +1,97 @@ +import { test, expect } from '@playwright/test'; + +// Test 1: Login page displays correctly (unauthenticated) +test('login page displays correctly', async ({ page }, testInfo) => { + // Skip if running with authenticated storageState + if (testInfo.project.name === 'default') { + testInfo.skip(); + } + + await page.goto('/login'); + + // Wait for page to load and check for German text + await expect(page.getByText('Mit ChurchTools anmelden')).toBeVisible({ timeout: 15000 }); + + // Check OAuth button is visible + await expect(page.getByTestId('login-oauth-button')).toBeVisible(); + + // Check Test Login button is visible (local env only) + await expect(page.getByTestId('login-test-button')).toBeVisible(); + + // Check German text is present + await expect(page.getByText('Melde dich mit deinem ChurchTools-Konto an, um fortzufahren.')).toBeVisible(); +}); + +// Test 2: Dummy test login works (authenticated via storageState) +test('dummy test login works', async ({ page }) => { + // Already logged in via storageState from auth.setup.ts + await page.goto('/dashboard'); + + // Wait for page to fully load + await page.waitForLoadState('networkidle'); + + // Verify we're on dashboard (not redirected to login) + // Note: If this fails, the storageState session may have expired + await expect(page).toHaveURL(/.*dashboard/); +}); + +// Test 3: Logout works (authenticated via storageState) +test('logout works', async ({ page }) => { + await page.goto('/dashboard'); + + // Wait for page to fully load + await page.waitForLoadState('networkidle'); + + // Verify we're on dashboard first + await expect(page).toHaveURL(/.*dashboard/); + + // Get XSRF token from cookies for CSRF protection + const cookies = await page.context().cookies(); + const xsrfCookie = cookies.find((c) => c.name === 'XSRF-TOKEN'); + const xsrfToken = xsrfCookie ? decodeURIComponent(xsrfCookie.value) : ''; + + // Make a POST request to logout endpoint with CSRF token + await page.request.post('/logout', { + headers: { + 'X-XSRF-TOKEN': xsrfToken, + }, + }); + + // Navigate to dashboard to verify we're logged out + await page.goto('/dashboard'); + + // Should redirect to login + await expect(page).toHaveURL(/.*login/); +}); + +// Test 4: Protected routes redirect to login when unauthenticated +test('protected routes redirect to login', async ({ page }, testInfo) => { + // Skip if running with authenticated storageState + if (testInfo.project.name === 'default') { + testInfo.skip(); + } + + // Try to access protected route + await page.goto('/services'); + + // Should redirect to login + await expect(page).toHaveURL(/.*login/); +}); + +// Test 5: OAuth button links to correct ChurchTools URL +test('oauth button links to churchtools', async ({ page }, testInfo) => { + // Skip if running with authenticated storageState + if (testInfo.project.name === 'default') { + testInfo.skip(); + } + + await page.goto('/login'); + + // Wait for page to load + await expect(page.getByText('Mit ChurchTools anmelden')).toBeVisible({ timeout: 15000 }); + + const oauthButton = page.getByTestId('login-oauth-button'); + + // Verify button has href attribute pointing to churchtools + await expect(oauthButton).toHaveAttribute('href', /churchtools/); +});