Local changes: Updated model training, removed debug instrumentation, and configuration improvements
This commit is contained in:
89
frontend/e2e/dashboard.spec.ts
Normal file
89
frontend/e2e/dashboard.spec.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Dashboard Page', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/')
|
||||
})
|
||||
|
||||
test('loads dashboard page', async ({ page }) => {
|
||||
await expect(page).toHaveTitle(/FXQ One|Crypto Trader/i)
|
||||
})
|
||||
|
||||
test('displays main sections', async ({ page }) => {
|
||||
// Check for main dashboard elements
|
||||
await expect(page.getByRole('heading', { level: 4 })).toBeVisible()
|
||||
|
||||
// Wait for content to load
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Check for navigation elements
|
||||
await expect(page.getByRole('navigation')).toBeVisible()
|
||||
})
|
||||
|
||||
test('displays autopilot configuration section', async ({ page }) => {
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Look for autopilot related elements
|
||||
await expect(page.getByText(/autopilot/i).first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('navigation works correctly', async ({ page }) => {
|
||||
// Navigate to different pages
|
||||
await page.click('text=Trading')
|
||||
await expect(page).toHaveURL(/.*trading/i)
|
||||
|
||||
await page.click('text=Portfolio')
|
||||
await expect(page).toHaveURL(/.*portfolio/i)
|
||||
|
||||
await page.click('text=Strategies')
|
||||
await expect(page).toHaveURL(/.*strateg/i)
|
||||
|
||||
await page.click('text=Settings')
|
||||
await expect(page).toHaveURL(/.*settings/i)
|
||||
|
||||
// Go back to dashboard
|
||||
await page.click('text=Dashboard')
|
||||
await expect(page).toHaveURL(/.*\/$/)
|
||||
})
|
||||
|
||||
test('displays real-time status indicators', async ({ page }) => {
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Look for status indicators (chips, badges, etc.)
|
||||
const statusChips = page.locator('.MuiChip-root')
|
||||
await expect(statusChips.first()).toBeVisible({ timeout: 10000 })
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Dashboard - Autopilot Controls', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('shows autopilot start button', async ({ page }) => {
|
||||
const startButton = page.getByRole('button', { name: /start.*autopilot/i })
|
||||
// Button should be visible
|
||||
await expect(startButton).toBeVisible({ timeout: 10000 })
|
||||
})
|
||||
|
||||
test('symbol selection is available', async ({ page }) => {
|
||||
// Look for symbol selector (autocomplete or select)
|
||||
const symbolInput = page.locator('[data-testid="autopilot-symbols"], .MuiAutocomplete-root, input[placeholder*="symbol" i]').first()
|
||||
await expect(symbolInput).toBeVisible({ timeout: 10000 })
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Dashboard - Charts', () => {
|
||||
test('chart grid displays', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Wait for charts to potentially load
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
// Look for chart container
|
||||
const chartArea = page.locator('[class*="chart"], canvas, svg').first()
|
||||
await expect(chartArea).toBeVisible({ timeout: 15000 })
|
||||
})
|
||||
})
|
||||
73
frontend/e2e/settings.spec.ts
Normal file
73
frontend/e2e/settings.spec.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Settings Page', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/settings')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('displays settings page title', async ({ page }) => {
|
||||
await expect(page.getByRole('heading', { name: /settings/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('shows exchange configuration section', async ({ page }) => {
|
||||
await expect(page.getByText(/exchange/i).first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('shows alert configuration section', async ({ page }) => {
|
||||
await expect(page.getByText(/alert/i).first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('has tabs for different settings categories', async ({ page }) => {
|
||||
// Look for tab navigation
|
||||
const tabs = page.getByRole('tab')
|
||||
await expect(tabs.first()).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Settings - Exchange Configuration', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/settings')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('shows add exchange option', async ({ page }) => {
|
||||
// Look for add exchange button or option
|
||||
const addExchange = page.getByRole('button', { name: /add.*exchange|new.*exchange|configure/i })
|
||||
await expect(addExchange.first()).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Settings - Performance', () => {
|
||||
test('page loads within reasonable time', async ({ page }) => {
|
||||
const startTime = Date.now()
|
||||
|
||||
await page.goto('/settings')
|
||||
await page.waitForLoadState('domcontentloaded')
|
||||
|
||||
const loadTime = Date.now() - startTime
|
||||
|
||||
// Page should load within 5 seconds
|
||||
expect(loadTime).toBeLessThan(5000)
|
||||
})
|
||||
|
||||
test('no console errors on load', async ({ page }) => {
|
||||
const errors: string[] = []
|
||||
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
errors.push(msg.text())
|
||||
}
|
||||
})
|
||||
|
||||
await page.goto('/settings')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Filter out known non-critical errors
|
||||
const criticalErrors = errors.filter(
|
||||
(e) => !e.includes('WebSocket') && !e.includes('Failed to load resource')
|
||||
)
|
||||
|
||||
expect(criticalErrors).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
79
frontend/e2e/strategies.spec.ts
Normal file
79
frontend/e2e/strategies.spec.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Strategies Page', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/strategies')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('displays strategies page title', async ({ page }) => {
|
||||
await expect(page.getByRole('heading', { name: /strateg/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('shows create strategy button', async ({ page }) => {
|
||||
const createButton = page.getByRole('button', { name: /create|new|add/i }).first()
|
||||
await expect(createButton).toBeVisible()
|
||||
})
|
||||
|
||||
test('displays strategy list or empty state', async ({ page }) => {
|
||||
// Either show strategies or empty state message
|
||||
const content = page.getByText(/no strategies|create your first|strategy/i).first()
|
||||
await expect(content).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Strategies - Create Strategy Flow', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/strategies')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('opens strategy creation dialog', async ({ page }) => {
|
||||
const createButton = page.getByRole('button', { name: /create|new|add/i }).first()
|
||||
await createButton.click()
|
||||
|
||||
// Dialog should open
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
})
|
||||
|
||||
test('strategy dialog has required fields', async ({ page }) => {
|
||||
const createButton = page.getByRole('button', { name: /create|new|add/i }).first()
|
||||
await createButton.click()
|
||||
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
|
||||
// Check for strategy name field
|
||||
await expect(page.getByLabel(/name/i)).toBeVisible()
|
||||
|
||||
// Check for strategy type selector
|
||||
await expect(page.getByLabel(/type|strategy type/i).or(page.getByText(/select.*strategy/i).first())).toBeVisible()
|
||||
})
|
||||
|
||||
test('shows available strategy types', async ({ page }) => {
|
||||
const createButton = page.getByRole('button', { name: /create|new|add/i }).first()
|
||||
await createButton.click()
|
||||
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
|
||||
// Open strategy type dropdown
|
||||
const typeSelector = page.getByLabel(/type|strategy type/i).or(
|
||||
page.locator('[data-testid="strategy-type-select"]')
|
||||
)
|
||||
await typeSelector.click()
|
||||
|
||||
// Should see strategy options like RSI, MACD, etc.
|
||||
await expect(page.getByRole('option').first()).toBeVisible({ timeout: 5000 })
|
||||
})
|
||||
|
||||
test('can cancel strategy creation', async ({ page }) => {
|
||||
const createButton = page.getByRole('button', { name: /create|new|add/i }).first()
|
||||
await createButton.click()
|
||||
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
|
||||
// Cancel
|
||||
await page.getByRole('button', { name: /cancel/i }).click()
|
||||
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
})
|
||||
})
|
||||
96
frontend/e2e/trading.spec.ts
Normal file
96
frontend/e2e/trading.spec.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Trading Page', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/trading')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('displays trading page title', async ({ page }) => {
|
||||
await expect(page.getByRole('heading', { name: /trading/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('shows order form button', async ({ page }) => {
|
||||
// Look for new order button or order form
|
||||
const orderButton = page.getByRole('button', { name: /new order|place order|create order/i })
|
||||
await expect(orderButton).toBeVisible()
|
||||
})
|
||||
|
||||
test('displays positions section', async ({ page }) => {
|
||||
// Look for positions area
|
||||
await expect(page.getByText(/positions/i).first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('displays orders section', async ({ page }) => {
|
||||
// Look for orders area
|
||||
await expect(page.getByText(/orders/i).first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('paper trading toggle is visible', async ({ page }) => {
|
||||
// Look for paper trading switch
|
||||
const paperToggle = page.getByRole('switch', { name: /paper/i }).or(
|
||||
page.getByText(/paper trading/i)
|
||||
)
|
||||
await expect(paperToggle.first()).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Trading - Order Form', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/trading')
|
||||
await page.waitForLoadState('networkidle')
|
||||
})
|
||||
|
||||
test('opens order form dialog', async ({ page }) => {
|
||||
// Click new order button
|
||||
const orderButton = page.getByRole('button', { name: /new order|place order|create order/i })
|
||||
await orderButton.click()
|
||||
|
||||
// Check dialog opens
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
})
|
||||
|
||||
test('order form has required fields', async ({ page }) => {
|
||||
// Open order form
|
||||
const orderButton = page.getByRole('button', { name: /new order|place order|create order/i })
|
||||
await orderButton.click()
|
||||
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
|
||||
// Check for symbol field
|
||||
await expect(page.getByLabel(/symbol/i)).toBeVisible()
|
||||
|
||||
// Check for quantity field
|
||||
await expect(page.getByLabel(/quantity|amount/i)).toBeVisible()
|
||||
|
||||
// Check for side selection (buy/sell)
|
||||
await expect(page.getByText(/buy|sell/i).first()).toBeVisible()
|
||||
|
||||
// Check for order type
|
||||
await expect(page.getByLabel(/order type|type/i)).toBeVisible()
|
||||
})
|
||||
|
||||
test('can close order form', async ({ page }) => {
|
||||
// Open order form
|
||||
const orderButton = page.getByRole('button', { name: /new order|place order|create order/i })
|
||||
await orderButton.click()
|
||||
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
|
||||
// Close dialog
|
||||
await page.getByRole('button', { name: /cancel|close/i }).click()
|
||||
|
||||
await expect(page.getByRole('dialog')).not.toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Trading - Balance Display', () => {
|
||||
test('shows balance information', async ({ page }) => {
|
||||
await page.goto('/trading')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Look for balance display
|
||||
const balanceText = page.getByText(/balance|total|available/i)
|
||||
await expect(balanceText.first()).toBeVisible()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user