Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution - Enhance API schema with expanded type definitions and resolvers - Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth - Implement new services: AI optimization, billing, blockchain, compliance, marketplace - Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage) - Update Crossplane provider with enhanced VM management capabilities - Add comprehensive test suite for API endpoints and services - Update frontend components with improved GraphQL subscriptions and real-time updates - Enhance security configurations and headers (CSP, CORS, etc.) - Update documentation and configuration files - Add new CI/CD workflows and validation scripts - Implement design system improvements and UI enhancements
This commit is contained in:
195
e2e/infrastructure-dashboard.spec.ts
Normal file
195
e2e/infrastructure-dashboard.spec.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
|
||||
test.describe('Infrastructure Dashboard', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs')
|
||||
})
|
||||
|
||||
test('should load dashboard', async ({ page }) => {
|
||||
await expect(page.getByRole('heading', { name: /infrastructure documentation/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('should navigate to topology page', async ({ page }) => {
|
||||
await page.getByRole('link', { name: /network topology/i }).click()
|
||||
await expect(page).toHaveURL(/.*\/infrastructure\/docs\/topology/)
|
||||
await expect(page.getByRole('heading', { name: /network topology/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('should navigate to compliance page', async ({ page }) => {
|
||||
await page.getByRole('link', { name: /compliance mapping/i }).click()
|
||||
await expect(page).toHaveURL(/.*\/infrastructure\/docs\/compliance/)
|
||||
await expect(page.getByRole('heading', { name: /compliance mapping/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('should navigate to timeline page', async ({ page }) => {
|
||||
await page.getByRole('link', { name: /deployment timeline/i }).click()
|
||||
await expect(page).toHaveURL(/.*\/infrastructure\/docs\/timeline/)
|
||||
await expect(page.getByRole('heading', { name: /deployment timeline/i })).toBeVisible()
|
||||
})
|
||||
|
||||
test('should navigate to costs page', async ({ page }) => {
|
||||
await page.getByRole('link', { name: /cost estimates/i }).click()
|
||||
await expect(page).toHaveURL(/.*\/infrastructure\/docs\/costs/)
|
||||
await expect(page.getByRole('heading', { name: /cost estimates/i })).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Network Topology', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs/topology')
|
||||
})
|
||||
|
||||
test('should display topology visualization', async ({ page }) => {
|
||||
// Wait for topology to load
|
||||
await page.waitForSelector('[id="topology-container"]', { timeout: 10000 })
|
||||
const container = page.locator('[id="topology-container"]')
|
||||
await expect(container).toBeVisible()
|
||||
})
|
||||
|
||||
test('should toggle edit mode', async ({ page }) => {
|
||||
const editToggle = page.getByRole('button', { name: /edit mode/i })
|
||||
await editToggle.click()
|
||||
// Verify edit mode is active (check for edit controls)
|
||||
await expect(page.getByText(/add node/i).or(page.getByText(/connect nodes/i))).toBeVisible({ timeout: 5000 })
|
||||
})
|
||||
|
||||
test('should export PNG', async ({ page }) => {
|
||||
const exportButton = page.getByRole('button', { name: /export png/i })
|
||||
await expect(exportButton).toBeVisible()
|
||||
// Note: Actual download testing requires additional setup
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Compliance Mapping', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs/compliance')
|
||||
})
|
||||
|
||||
test('should display compliance table', async ({ page }) => {
|
||||
await page.waitForSelector('table', { timeout: 5000 })
|
||||
const table = page.locator('table')
|
||||
await expect(table).toBeVisible()
|
||||
})
|
||||
|
||||
test('should filter by region', async ({ page }) => {
|
||||
const regionSelector = page.getByRole('combobox', { name: /region/i })
|
||||
await regionSelector.click()
|
||||
await page.getByText('Europe').click()
|
||||
// Verify filter is applied
|
||||
await expect(regionSelector).toContainText('Europe')
|
||||
})
|
||||
|
||||
test('should search countries', async ({ page }) => {
|
||||
const searchInput = page.getByPlaceholder(/search countries/i)
|
||||
await searchInput.fill('Italy')
|
||||
// Verify search is working (table should update)
|
||||
await page.waitForTimeout(500) // Wait for debounce
|
||||
})
|
||||
|
||||
test('should toggle edit mode and show bulk actions', async ({ page }) => {
|
||||
const editToggle = page.getByRole('button', { name: /edit mode/i })
|
||||
await editToggle.click()
|
||||
// Checkboxes should appear
|
||||
await expect(page.locator('input[type="checkbox"]').first()).toBeVisible({ timeout: 2000 })
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Deployment Timeline', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs/timeline')
|
||||
})
|
||||
|
||||
test('should display Gantt chart', async ({ page }) => {
|
||||
await page.waitForSelector('.echarts-for-react', { timeout: 5000 })
|
||||
const chart = page.locator('.echarts-for-react')
|
||||
await expect(chart).toBeVisible()
|
||||
})
|
||||
|
||||
test('should add milestone in edit mode', async ({ page }) => {
|
||||
const editToggle = page.getByRole('button', { name: /edit mode/i })
|
||||
await editToggle.click()
|
||||
|
||||
const addButton = page.getByRole('button', { name: /add milestone/i })
|
||||
await addButton.click()
|
||||
|
||||
// Dialog should open
|
||||
await expect(page.getByRole('dialog')).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Cost Estimates', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs/costs')
|
||||
})
|
||||
|
||||
test('should display cost charts', async ({ page }) => {
|
||||
await page.waitForSelector('.echarts-for-react', { timeout: 5000 })
|
||||
const charts = page.locator('.echarts-for-react')
|
||||
await expect(charts.first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('should export Excel', async ({ page }) => {
|
||||
const exportButton = page.getByRole('button', { name: /export excel/i })
|
||||
await expect(exportButton).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Global Search', () => {
|
||||
test('should open search dialog', async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs')
|
||||
await page.keyboard.press('Control+f')
|
||||
// Search dialog should open
|
||||
await expect(page.getByRole('dialog', { name: /global search/i })).toBeVisible({ timeout: 2000 })
|
||||
})
|
||||
|
||||
test('should search and navigate', async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs')
|
||||
const searchButton = page.getByRole('button', { name: /search/i })
|
||||
await searchButton.click()
|
||||
|
||||
const searchInput = page.getByPlaceholder(/search countries/i)
|
||||
await searchInput.fill('Italy')
|
||||
|
||||
// Wait for results
|
||||
await page.waitForTimeout(500)
|
||||
// Click first result if available
|
||||
const firstResult = page.locator('button').filter({ hasText: /italy/i }).first()
|
||||
if (await firstResult.isVisible()) {
|
||||
await firstResult.click()
|
||||
// Should navigate to result page
|
||||
await page.waitForURL(/.*\/infrastructure\/docs/)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Keyboard Shortcuts', () => {
|
||||
test('should toggle edit mode with Ctrl+E', async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs/topology')
|
||||
await page.keyboard.press('Control+e')
|
||||
// Edit mode should toggle
|
||||
await page.waitForTimeout(500)
|
||||
})
|
||||
|
||||
test('should show shortcuts dialog with Ctrl+/', async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs/topology')
|
||||
await page.keyboard.press('Control+/')
|
||||
await expect(page.getByRole('dialog', { name: /keyboard shortcuts/i })).toBeVisible({ timeout: 2000 })
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Accessibility', () => {
|
||||
test('should have skip link', async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs')
|
||||
const skipLink = page.getByRole('link', { name: /skip to main content/i })
|
||||
await expect(skipLink).toBeVisible()
|
||||
})
|
||||
|
||||
test('should navigate with keyboard', async ({ page }) => {
|
||||
await page.goto('/infrastructure/docs')
|
||||
await page.keyboard.press('Tab')
|
||||
// Should focus on first interactive element
|
||||
const focused = page.locator(':focus')
|
||||
await expect(focused).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user