bytelyst-devops-tools/dashboard/web/e2e/dashboard.spec.ts

104 lines
3.9 KiB
TypeScript

import { test, expect } from '@playwright/test';
const adminUser = {
id: 'user-1',
email: 'admin@example.test',
role: 'admin',
plan: 'internal',
displayName: 'Dashboard Admin',
emailVerified: true,
currentProduct: 'bytelyst-devops',
products: [{ productId: 'bytelyst-devops', plan: 'internal', role: 'admin' }],
mfaEnabled: false,
mfaMethods: [],
};
const services = [
{
id: 'trading',
name: 'Investment Trading',
scriptPath: '../deploy-invttrdg.sh',
healthUrl: 'https://api.bytelyst.com/invttrdg/health',
repoPath: '../learning_ai_invt_trdg',
status: 'up',
version: '1.2.3',
productId: 'bytelyst-devops',
},
];
const deployments = [
{
id: 'deploy-1',
serviceId: 'trading',
version: '1.2.3',
status: 'success',
logs: 'deployment completed',
triggeredBy: 'user-1',
triggeredAt: new Date('2026-05-25T08:00:00Z').toISOString(),
completedAt: new Date('2026-05-25T08:01:00Z').toISOString(),
productId: 'bytelyst-devops',
},
];
test.describe('DevOps Dashboard', () => {
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
window.localStorage.setItem('access_token', 'e2e-access-token');
window.localStorage.setItem('refresh_token', 'e2e-refresh-token');
});
await page.route('**/auth/me', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(adminUser) });
});
await page.route('**/api/csrf-token', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ csrfToken: 'csrf-token' }) });
});
await page.route('**/api/services', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(services) });
});
await page.route('**/api/deployments?limit=10', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(deployments) });
});
await page.route('**/api/health/cache', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ message: 'Cache cleared' }) });
});
await page.route('**/api/seed', async (route) => {
await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ message: 'Seeded default services' }) });
});
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});
test('renders services, deployments, and action controls', async ({ page }) => {
await expect(page.getByText('Services and deployments overview')).toBeVisible();
await expect(page.getByRole('button', { name: /refresh/i })).toBeVisible();
await expect(page.getByRole('button', { name: /create service/i })).toBeVisible();
await expect(page.getByRole('button', { name: /seed services/i })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Investment Trading' })).toBeVisible();
await expect(page.getByText('Recent Deployments')).toBeVisible();
await expect(page.getByRole('cell', { name: '1.2.3' })).toBeVisible();
});
test('refreshes service and deployment data', async ({ page }) => {
const refreshButton = page.getByRole('button', { name: /refresh/i });
await refreshButton.click();
await expect(refreshButton).toBeEnabled();
await expect(page.getByRole('heading', { name: 'Investment Trading' })).toBeVisible();
});
});
test('login page renders the platform credential form without baked-in credentials', async ({ page }) => {
await page.goto('/login');
await expect(page.getByRole('heading', { name: 'DevOps Dashboard Login' })).toBeVisible();
await expect(page.getByLabel('Email')).toHaveValue('');
await expect(page.getByLabel('Password')).toHaveValue('');
await expect(page.getByLabel('Product ID')).toHaveValue('bytelyst-devops');
});