import { test, expect } from '../support/fixtures'; import { faker } from '@faker-js/faker'; test.describe('Settings Management (Story 4.1, 4.4)', () => { test.beforeEach(async ({ page }) => { await page.goto('/settings'); }); test('[P1] should configure a new LLM provider', async ({ page }) => { // Mock validation request await page.route('/api/llm', async route => { const body = JSON.parse(route.request().postData() || '{}'); // Check if it's a validation request (has 'hello' message usually, see LLMService) or just success await route.fulfill({ status: 200, body: JSON.stringify({ success: true, data: { text: 'Validation success' } }) }); }); // GIVEN: User is on settings page const providerName = `Custom Provider ${faker.number.int({ min: 1000 })}`; const baseUrl = faker.internet.url(); const modelName = 'gpt-4-custom'; const apiKey = 'sk-test-key-' + faker.string.alphanumeric(10); // WHEN: User clicks Add New Provider await page.getByRole('button', { name: /add new provider/i }).click(); // THEN: Dialog should open await expect(page.getByRole('dialog')).toBeVisible(); // WHEN: User fills in the form await page.getByLabel('Provider Name').fill(providerName); await page.getByLabel('Base URL').fill(baseUrl); await page.getByLabel('Model Name').fill(modelName); await page.getByPlaceholder('sk-...').fill(apiKey); // WHEN: User saves (Button text depends on mode, usually "Save & Validate" or "Save as New Provider") // "Save as New Provider" is likely for Add mode await page.getByRole('button', { name: /save/i }).click(); // THEN: Dialog should close await expect(page.getByRole('dialog')).toBeHidden(); // THEN: New provider should appear in the list await expect(page.getByText(providerName)).toBeVisible(); await expect(page.getByText(modelName)).toBeVisible(); }); test('[P1] should switch active provider', async ({ page }) => { // GIVEN: A provider exists (using the default one from store or we just add one) // Since we don't inject store here (unless we want to refactor to do so), // we might rely on default empty state and add one, OR we assume persistence from previous test if workers reused (not guaranteed). // Best to add one first or inject state. Let's add one quickly via UI to be safe/independent. const providerName = `Switch Test Provider ${faker.number.int()}`; await page.getByRole('button', { name: /add new provider/i }).click(); await page.getByLabel('Provider Name').fill(providerName); await page.getByLabel('Base URL').fill('https://api.example.com'); await page.getByLabel('Model Name').fill('gpt-test'); await page.getByPlaceholder('sk-...').fill('sk-test'); // Mock validation for this save too await page.getByRole('button', { name: /save/i }).click(); // WHEN: User selects the new provider in the selector // The selector uses radio behavior or clickable cards await page.getByText(providerName).click(); // THEN: It should become active // We check for the data-active attribute or visual indicator // Based on test: closest('[data-active]') const providerCard = page.getByText(providerName).locator('xpath=ancestor::*[contains(@data-active, "true") or contains(@data-active, "false")]').first(); await expect(providerCard).toHaveAttribute('data-active', 'true'); }); test('[P0] should enforce Key Storage Security (Obfuscation)', async ({ page }) => { const secretKey = 'sk-secret-key-12345'; // Mock validation request await page.route('/api/llm', async route => { await route.fulfill({ status: 200, body: JSON.stringify({ success: true, data: { text: 'Validation success' } }) }); }); // Open Modal await page.getByRole('button', { name: /add new provider/i }).click(); // Fill Sensitive Data await page.getByLabel('Provider Name').fill('Security Test'); await page.getByLabel('Base URL').fill('https://api.openai.com/v1'); await page.getByLabel('Model Name').fill('gpt-4'); await page.getByPlaceholder('sk-...').fill(secretKey); await page.getByRole('button', { name: /save/i }).click(); await expect(page.getByRole('dialog')).toBeHidden(); // Verify key is NOT stored in plain text in localStorage const settings = await page.evaluate(() => localStorage.getItem('test01-settings-storage')); expect(settings).not.toBeNull(); expect(settings).not.toContain(secretKey); // Should be base64 encoded }); test('[P2] should validate provider inputs', async ({ page }) => { // WHEN: User clicks Add New Provider await page.getByRole('button', { name: /add new provider/i }).click(); // WHEN: User tries to save empty form await page.getByRole('button', { name: /save/i }).click(); // THEN: validation errors should appear (assuming HTML5 validation or UI errors) // Since component uses Radix UI or similar, we might check for :invalid state or error messages // For now, check that dialog is still open await expect(page.getByRole('dialog')).toBeVisible(); }); });