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>
This commit is contained in:
86
tests/e2e/settings-byod.spec.ts
Normal file
86
tests/e2e/settings-byod.spec.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user