- Add timeout to auth check to prevent hanging on API failures - Add timeout to API requests to prevent infinite loading - Add proper error state and error messages to dashboard - Show empty states when no services/deployments are available - Update E2E tests to handle authentication properly - Improve user feedback when API is unavailable This fixes the "Loading..." hang issue when backend APIs are unavailable and provides better user experience with clear error messages and retry options. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('DevOps Dashboard E2E Tests', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
// Navigate to login page first
|
|
await page.goto('http://localhost:3000/login');
|
|
|
|
// Fill in login form
|
|
await page.fill('input[type="email"]', 'admin@bytelyst.com');
|
|
await page.fill('input[type="password"]', 'admin12345');
|
|
await page.fill('input[type="text"]', 'bytelyst-devops');
|
|
|
|
// Submit login
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Wait for navigation to dashboard
|
|
await page.waitForURL('http://localhost:3000/', { timeout: 10000 });
|
|
});
|
|
|
|
test('dashboard page loads successfully', async ({ page }) => {
|
|
// Check main heading
|
|
await expect(page.getByText('Dashboard')).toBeVisible();
|
|
await expect(page.getByText('Services and deployments overview')).toBeVisible();
|
|
});
|
|
|
|
test('refresh button is visible', async ({ page }) => {
|
|
await expect(page.getByRole('button', { name: /refresh/i })).toBeVisible();
|
|
});
|
|
|
|
test('create service button is visible', async ({ page }) => {
|
|
await expect(page.getByRole('button', { name: /create service/i })).toBeVisible();
|
|
});
|
|
|
|
test('seed services button is visible', async ({ page }) => {
|
|
await expect(page.getByRole('button', { name: /seed services/i })).toBeVisible();
|
|
});
|
|
|
|
test('services section is visible', async ({ page }) => {
|
|
await expect(page.getByText('Services')).toBeVisible();
|
|
});
|
|
|
|
test('recent deployments section is visible', async ({ page }) => {
|
|
await expect(page.getByText('Recent Deployments')).toBeVisible();
|
|
});
|
|
|
|
test('refresh button works', async ({ page }) => {
|
|
const refreshButton = page.getByRole('button', { name: /refresh/i }).first();
|
|
await refreshButton.click();
|
|
// Check that button shows loading state
|
|
await expect(refreshButton).toBeDisabled();
|
|
});
|
|
|
|
test('shows empty state when no services', async ({ page }) => {
|
|
// Check for empty state message
|
|
const emptyState = page.getByText('No services configured');
|
|
if (await emptyState.isVisible()) {
|
|
await expect(page.getByText('Create Service')).toBeVisible();
|
|
}
|
|
});
|
|
});
|