Next-level improvements: 15 items across backend, frontend, and testing
Backend: - SQLiteStateBackend: persistent task/trace storage with SQLite - InMemoryStateBackend: in-memory impl of StateBackend interface - Redis cache backend (CacheBackend ABC + MemoryCacheBackend + RedisCacheBackend) - OpenAI adapter: async acomplete() with retry logic - Per-tenant + per-IP rate limiting in middleware Frontend: - State management: useStore + useAppState (zero-dep, context + reducer) - React Router integration: URL-based navigation (usePageNavigation) - WebSocket streaming: sendPrompt + StreamCallbacks for token-by-token updates - File preview: inline image/text/binary preview with expand/collapse - Sparkline charts + MetricCard + BarChart for dashboard visualization - Push notifications hook (useNotifications) with browser Notification API - i18n system: 6 locales (en, es, fr, de, ja, zh) with interpolation - 6 new Storybook stories (ChatMessage, Skeleton, Markdown, SearchFilter, Toast, FilePreview) Testing: - Playwright E2E config + 6 browser specs (desktop + mobile) - 18 new Python tests (SQLiteStateBackend, InMemoryStateBackend, cache backends) 570 Python tests + 45 frontend tests = 615 total, 0 ruff errors. Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
This commit is contained in:
77
frontend/e2e/app.spec.ts
Normal file
77
frontend/e2e/app.spec.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* End-to-end tests for FusionAGI frontend.
|
||||
*
|
||||
* Prerequisites:
|
||||
* npx playwright install chromium
|
||||
* npm run dev (or the webServer config will start it)
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('FusionAGI App', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Set auth token to skip login
|
||||
await page.addInitScript(() => {
|
||||
localStorage.setItem('fusionagi-token', 'test-e2e-token')
|
||||
})
|
||||
})
|
||||
|
||||
test('renders the main interface', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
await expect(page.locator('.app')).toBeVisible()
|
||||
await expect(page.locator('.logo')).toContainText('FusionAGI')
|
||||
})
|
||||
|
||||
test('navigation tabs work', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
const tabs = page.locator('[role="tab"]')
|
||||
await expect(tabs).toHaveCount(4)
|
||||
|
||||
// Navigate to admin
|
||||
await tabs.filter({ hasText: 'Admin' }).click()
|
||||
await expect(page.locator('.admin-page, [role="status"]')).toBeVisible()
|
||||
|
||||
// Navigate to settings
|
||||
await tabs.filter({ hasText: 'Settings' }).click()
|
||||
await expect(page.locator('.settings-page, [role="form"]')).toBeVisible()
|
||||
})
|
||||
|
||||
test('theme toggle works', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
const app = page.locator('.app')
|
||||
const initialTheme = await app.getAttribute('data-theme')
|
||||
|
||||
await page.click('[aria-label*="mode"]')
|
||||
const newTheme = await app.getAttribute('data-theme')
|
||||
expect(newTheme).not.toBe(initialTheme)
|
||||
})
|
||||
|
||||
test('prompt input accepts text', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
const input = page.locator('[aria-label="Message input"]')
|
||||
await input.fill('Hello FusionAGI')
|
||||
await expect(input).toHaveValue('Hello FusionAGI')
|
||||
})
|
||||
|
||||
test('login page shows when not authenticated', async ({ page }) => {
|
||||
await page.addInitScript(() => {
|
||||
localStorage.removeItem('fusionagi-token')
|
||||
})
|
||||
await page.goto('/')
|
||||
await expect(page.locator('.login-page, input[type="password"], input[type="text"]')).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Mobile', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.addInitScript(() => {
|
||||
localStorage.setItem('fusionagi-token', 'test-e2e-token')
|
||||
})
|
||||
})
|
||||
|
||||
test('renders on mobile viewport', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 812 })
|
||||
await page.goto('/')
|
||||
await expect(page.locator('.app')).toBeVisible()
|
||||
})
|
||||
})
|
||||
28
frontend/e2e/playwright.config.ts
Normal file
28
frontend/e2e/playwright.config.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Playwright configuration for FusionAGI E2E tests.
|
||||
*
|
||||
* Run: npx playwright test
|
||||
* Requires: npx playwright install chromium
|
||||
*/
|
||||
|
||||
import { defineConfig, devices } from '@playwright/test'
|
||||
|
||||
export default defineConfig({
|
||||
testDir: '.',
|
||||
timeout: 30000,
|
||||
retries: 1,
|
||||
use: {
|
||||
baseURL: 'http://localhost:5173',
|
||||
trace: 'on-first-retry',
|
||||
screenshot: 'only-on-failure',
|
||||
},
|
||||
projects: [
|
||||
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
||||
{ name: 'mobile', use: { ...devices['iPhone 13'] } },
|
||||
],
|
||||
webServer: {
|
||||
command: 'npm run dev',
|
||||
port: 5173,
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user