import { test, expect } from '@playwright/test'; import * as auth from '../fixtures/auth'; import * as assertions from '../utils/assertions'; import * as helpers from '../utils/helpers'; import { LOCAL_USERS, TEST_CATEGORIES } from '../fixtures/test-data'; test.describe('Admin Settings Workflow', () => { const BASE_URL = process.env.BASE_URL || 'http://localhost:8917'; test.beforeEach(async ({ page }) => { // Navigate to app and login as admin await page.goto(BASE_URL); await auth.loginWithLocalUser(page, LOCAL_USERS.admin, BASE_URL); await assertions.assertUserAuthenticated(page, BASE_URL); // Open admin panel const adminButton = page.locator('[data-testid="admin-button"]'); await adminButton.click(); // Wait for admin overlay to appear await assertions.assertAdminDashboardVisible(page); }); test('should display admin dashboard with all tabs', async ({ page }) => { await assertions.assertAdminDashboardVisible(page); // Verify all tabs are present const identityTab = page.locator('[data-testid="admin-tab-identity"]'); const databaseTab = page.locator('[data-testid="admin-tab-database"]'); const ldapTab = page.locator('[data-testid="admin-tab-ldap"]'); const aiTab = page.locator('[data-testid="admin-tab-ai"]'); const categoriesTab = page.locator('[data-testid="admin-tab-categories"]'); await expect(identityTab).toBeVisible(); await expect(databaseTab).toBeVisible(); await expect(ldapTab).toBeVisible(); await expect(aiTab).toBeVisible(); await expect(categoriesTab).toBeVisible(); }); test('should display users in identity tab', async ({ page }) => { const identityTab = page.locator('[data-testid="admin-tab-identity"]'); await identityTab.click(); // User list should be displayed const userList = page.locator('[data-testid="user-list"]'); await expect(userList).toBeVisible(); // Should have at least one user (admin) const userItems = page.locator('[data-testid="user-list-item"]'); const count = await userItems.count(); expect(count).toBeGreaterThanOrEqual(1); }); test('should allow creating new user', async ({ page }) => { const identityTab = page.locator('[data-testid="admin-tab-identity"]'); await identityTab.click(); // Click add user button const addUserButton = page.locator('[data-testid="add-user-button"]'); await addUserButton.click(); // Modal should appear const modal = page.locator('[data-testid="create-user-modal"]'); await expect(modal).toBeVisible(); // Fill form await page.fill('[data-testid="new-user-name"]', 'TestUser123'); await page.fill('[data-testid="new-user-password"]', 'Password123!'); // Submit const submitButton = page.locator('[data-testid="create-user-submit"]'); await submitButton.click(); // Should show success const successToast = page.locator('[data-testid="toast-success"]'); await expect(successToast).toBeVisible({ timeout: 5000 }); }); test('should allow deleting user with confirmation', async ({ page }) => { const identityTab = page.locator('[data-testid="admin-tab-identity"]'); await identityTab.click(); // Find a non-admin user to delete const deleteButtons = page.locator('[data-testid="delete-user-button"]'); if (await deleteButtons.count() > 0) { // Click delete on first user await deleteButtons.first().click(); // Confirmation should appear const confirmDialog = page.locator('[data-testid="confirmation-modal"]'); await expect(confirmDialog).toBeVisible(); // Confirm deletion const confirmButton = page.locator('[data-testid="confirm-action"]'); await confirmButton.click(); // Should show success const successToast = page.locator('[data-testid="toast-success"]'); await expect(successToast).toBeVisible({ timeout: 5000 }); } }); test('should display database info in database tab', async ({ page }) => { const databaseTab = page.locator('[data-testid="admin-tab-database"]'); await databaseTab.click(); // Database info should be displayed const dbInfo = page.locator('[data-testid="database-info"]'); await expect(dbInfo).toBeVisible(); // Should show stats const itemCount = page.locator('[data-testid="item-count"]'); if (await itemCount.isVisible()) { const count = await itemCount.textContent(); expect(count).toMatch(/\d+/); } }); test('should allow backup creation', async ({ page }) => { const databaseTab = page.locator('[data-testid="admin-tab-database"]'); await databaseTab.click(); // Backup button should be present const backupButton = page.locator('[data-testid="backup-button"]'); if (await backupButton.isVisible()) { await backupButton.click(); // Should show progress or success const progressOrSuccess = page.locator( '[data-testid="backup-progress"], [data-testid="backup-success"]' ); await expect(progressOrSuccess).toBeVisible({ timeout: 10000 }); } }); test('should display LDAP configuration in ldap tab', async ({ page }) => { const ldapTab = page.locator('[data-testid="admin-tab-ldap"]'); await ldapTab.click(); // LDAP config should be displayed const ldapConfig = page.locator('[data-testid="ldap-config"]'); await expect(ldapConfig).toBeVisible(); }); test('should allow enabling/disabling LDAP', async ({ page }) => { const ldapTab = page.locator('[data-testid="admin-tab-ldap"]'); await ldapTab.click(); // Toggle LDAP const ldapToggle = page.locator('[data-testid="ldap-enabled-toggle"]'); if (await ldapToggle.isVisible()) { const initialState = await ldapToggle.isChecked(); // Click toggle await ldapToggle.click(); // Verify state changed const newState = await ldapToggle.isChecked(); expect(newState).not.toBe(initialState); } }); test('should allow saving LDAP settings', async ({ page }) => { const ldapTab = page.locator('[data-testid="admin-tab-ldap"]'); await ldapTab.click(); // Modify LDAP setting const ldapServerInput = page.locator('[data-testid="ldap-server-input"]'); if (await ldapServerInput.isVisible()) { const currentValue = await ldapServerInput.inputValue(); await ldapServerInput.fill('ldap.example.com'); // Save const saveButton = page.locator('[data-testid="save-settings-button"]'); await saveButton.click(); // Should show success const successToast = page.locator('[data-testid="toast-success"]'); await expect(successToast).toBeVisible({ timeout: 5000 }); } }); test('should display AI configuration in ai tab', async ({ page }) => { const aiTab = page.locator('[data-testid="admin-tab-ai"]'); await aiTab.click(); // AI config should be displayed const aiConfig = page.locator('[data-testid="ai-config"]'); await expect(aiConfig).toBeVisible(); // Provider selection should be visible const providerSelect = page.locator('[data-testid="ai-provider-select"]'); await expect(providerSelect).toBeVisible(); }); test('should allow selecting AI provider', async ({ page }) => { const aiTab = page.locator('[data-testid="admin-tab-ai"]'); await aiTab.click(); const providerSelect = page.locator('[data-testid="ai-provider-select"]'); const options = page.locator('[data-testid="provider-option"]'); if (await options.count() > 1) { // Select second option await options.nth(1).click(); // Should trigger save const successToast = page.locator('[data-testid="toast-success"]'); if (await successToast.isVisible({ timeout: 1000 }).catch(() => false)) { await expect(successToast).toBeVisible(); } } }); test('should allow entering API keys', async ({ page }) => { const aiTab = page.locator('[data-testid="admin-tab-ai"]'); await aiTab.click(); // API key input should be present const apiKeyInput = page.locator('[data-testid="ai-api-key-input"]'); if (await apiKeyInput.isVisible()) { await apiKeyInput.fill('test-api-key-12345'); // Key should be masked const inputType = await apiKeyInput.getAttribute('type'); expect(inputType).toBe('password'); // Save const saveButton = page.locator('[data-testid="save-settings-button"]'); if (await saveButton.isVisible()) { await saveButton.click(); } } }); test('should display categories list in categories tab', async ({ page }) => { const categoriesTab = page.locator('[data-testid="admin-tab-categories"]'); await categoriesTab.click(); // Categories list should be displayed const categoryList = page.locator('[data-testid="category-list"]'); await expect(categoryList).toBeVisible(); // Should have category items const categoryItems = page.locator('[data-testid="category-item"]'); const count = await categoryItems.count(); expect(count).toBeGreaterThanOrEqual(1); }); test('should allow adding new category', async ({ page }) => { const categoriesTab = page.locator('[data-testid="admin-tab-categories"]'); await categoriesTab.click(); // Add category button const addButton = page.locator('[data-testid="add-category-button"]'); if (await addButton.isVisible()) { await addButton.click(); // Form should appear const categoryForm = page.locator('[data-testid="category-form"]'); await expect(categoryForm).toBeVisible(); // Fill form const nameInput = page.locator('[data-testid="category-name-input"]'); await nameInput.fill('New Category'); // Submit const submitButton = page.locator('[data-testid="add-category-submit"]'); await submitButton.click(); // Should show success const successToast = page.locator('[data-testid="toast-success"]'); await expect(successToast).toBeVisible({ timeout: 5000 }); } }); test('should allow deleting category', async ({ page }) => { const categoriesTab = page.locator('[data-testid="admin-tab-categories"]'); await categoriesTab.click(); // Delete button const deleteButtons = page.locator('[data-testid="delete-category-button"]'); if (await deleteButtons.count() > 0) { await deleteButtons.first().click(); // Confirmation should appear const confirmDialog = page.locator('[data-testid="confirmation-modal"]'); await expect(confirmDialog).toBeVisible(); // Confirm const confirmButton = page.locator('[data-testid="confirm-action"]'); await confirmButton.click(); // Should show success const successToast = page.locator('[data-testid="toast-success"]'); await expect(successToast).toBeVisible({ timeout: 5000 }); } }); test('should close admin dashboard', async ({ page }) => { // Close button should be present const closeButton = page.locator('[data-testid="close-admin-overlay"]'); if (await closeButton.isVisible()) { await closeButton.click(); // Admin overlay should close const adminOverlay = page.locator('[data-testid="admin-overlay"]'); await expect(adminOverlay).not.toBeVisible({ timeout: 3000 }); } }); test('should prevent non-admin users from accessing admin panel', async ({ page }) => { // Login as regular user first await page.goto(BASE_URL); await auth.logout(page, BASE_URL); // Login with regular user (if available) await page.goto(BASE_URL); // Try to access admin endpoint directly await page.goto(`${BASE_URL}/admin`); // Should be redirected or show error const adminOverlay = page.locator('[data-testid="admin-overlay"]'); const errorMessage = page.locator('[data-testid="unauthorized-error"]'); const isBlocked = !(await adminOverlay.isVisible().catch(() => false)) || (await errorMessage.isVisible().catch(() => false)); expect(isBlocked).toBe(true); }); });