Files
brachnha-insight/tests/e2e/settings-byod.spec.ts
Max 3fbbb1a93b Initial commit: Brachnha Insight project setup
- Next.js 14+ with App Router and TypeScript
- Tailwind CSS and ShadCN UI styling
- Zustand state management
- Dexie.js for IndexedDB (local-first data)
- Auth.js v5 for authentication
- BMAD framework integration

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-26 12:28:43 +07:00

87 lines
3.8 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Epic 4: Power User Settings (BYOD)', () => {
test.beforeEach(async ({ page }) => {
// Clear storage to ensure clean state
await page.goto('/');
await page.evaluate(() => localStorage.clear());
// Mock API responses for validation
await page.route('**/chat/completions', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ choices: [{ message: { content: 'mock success' } }] })
});
});
});
test('P0: Provider Switching Configuration', async ({ page }) => {
// Navigate to settings
await page.goto('/settings');
await expect(page).toHaveURL(/.*settings/);
// 1. Add First Provider
await page.getByRole('button', { name: 'Add Provider', exact: true }).click();
await expect(page.getByRole('dialog')).toBeVisible();
// Fill Provider 1
await page.getByRole('textbox', { name: /Provider Name/i }).fill('Mock Provider 1');
await page.getByRole('textbox', { name: /Base URL/i }).fill('https://mock-provider-1.com/v1');
await page.getByRole('textbox', { name: /API Key/i }).fill('sk-key-1');
await page.getByRole('textbox', { name: /Model Name/i }).fill('model-1');
await page.getByRole('button', { name: /Save/i }).click();
// Verify Modal Closes (implicit success check)
await expect(page.getByRole('dialog')).toBeHidden();
// 2. Add Second Provider (Switching Test)
await page.getByRole('button', { name: 'Add Provider', exact: true }).click();
await expect(page.getByRole('dialog')).toBeVisible();
// Fill Provider 2
await page.getByRole('textbox', { name: /Provider Name/i }).fill('Mock Provider 2');
await page.getByRole('textbox', { name: /Base URL/i }).fill('https://mock-provider-2.com/v1');
await page.getByRole('textbox', { name: /API Key/i }).fill('sk-key-2');
await page.getByRole('textbox', { name: /Model Name/i }).fill('model-2');
await page.getByRole('button', { name: /Save/i }).click();
await expect(page.getByRole('dialog')).toBeHidden();
// 3. Verify Local Storage has the LATEST active provider (Model 2)
const settings = await page.evaluate(() => localStorage);
const storageString = JSON.stringify(settings);
console.log('Storage:', storageString);
expect(storageString).toContain('https://mock-provider-2.com/v1');
expect(storageString).toContain('model-2');
});
test('P0: Key Storage Security (Obfuscation)', async ({ page }) => {
await page.goto('/settings');
const secretKey = 'sk-secret-key-12345';
// Open Modal
await page.getByRole('button', { name: 'Add Provider', exact: true }).click();
// Fill Sensitive Data
await page.getByRole('textbox', { name: /Provider Name/i }).fill('Security Test');
await page.getByRole('textbox', { name: /Base URL/i }).fill('https://api.openai.com/v1');
await page.getByRole('textbox', { name: /API Key/i }).fill(secretKey);
await page.getByRole('textbox', { name: /Model Name/i }).fill('gpt-4');
await page.getByRole('button', { name: /Save/i }).click();
await expect(page.getByRole('dialog')).toBeHidden();
// Verify key is NOT stored in plain text
const settings = await page.evaluate(() => localStorage);
const storageValues = Object.values(settings).join('');
// The raw key should NOT be found exactly as entered if obfuscation works
// Note: If this fails, it means Security P0 Failed (Critical Issue)
expect(storageValues).not.toContain(secretKey);
});
});