Files
hive/frontend/e2e/auth.spec.ts
anthonyrawlins aacb45156b Set up comprehensive frontend testing infrastructure
- Install Jest for unit testing with React Testing Library
- Install Playwright for end-to-end testing
- Configure Jest with proper TypeScript support and module mapping
- Create test setup files and utilities for both unit and e2e tests

Components:
* Jest configuration with coverage thresholds
* Playwright configuration with browser automation
* Unit tests for LoginForm, AuthContext, and useSocketIO hook
* E2E tests for authentication, dashboard, and agents workflows
* GitHub Actions workflow for automated testing
* Mock data and API utilities for consistent testing
* Test documentation with best practices

Testing features:
- Unit tests with 70% coverage threshold
- E2E tests with API mocking and user journey testing
- CI/CD integration for automated test runs
- Cross-browser testing support with Playwright
- Authentication system testing end-to-end

🚀 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 14:06:34 +10:00

175 lines
5.7 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Authentication Flow', () => {
test.beforeEach(async ({ page }) => {
// Start fresh for each test
await page.goto('/');
});
test('should display login form on unauthenticated access', async ({ page }) => {
// Should redirect to login page
await expect(page).toHaveURL(/.*\/login/);
// Check login form elements
await expect(page.getByRole('heading', { name: /sign in/i })).toBeVisible();
await expect(page.getByLabel(/email/i)).toBeVisible();
await expect(page.getByLabel(/password/i)).toBeVisible();
await expect(page.getByRole('button', { name: /sign in/i })).toBeVisible();
});
test('should show validation errors for empty login form', async ({ page }) => {
await page.goto('/login');
// Try to submit empty form
await page.getByRole('button', { name: /sign in/i }).click();
// Check for validation errors
await expect(page.getByText(/email is required/i)).toBeVisible();
await expect(page.getByText(/password is required/i)).toBeVisible();
});
test('should show error for invalid email format', async ({ page }) => {
await page.goto('/login');
// Enter invalid email
await page.getByLabel(/email/i).fill('invalid-email');
await page.getByLabel(/password/i).fill('password123');
await page.getByRole('button', { name: /sign in/i }).click();
// Check for validation error
await expect(page.getByText(/invalid email format/i)).toBeVisible();
});
test('should handle login failure gracefully', async ({ page }) => {
await page.goto('/login');
// Mock failed login response
await page.route('**/api/auth/login', async route => {
await route.fulfill({
status: 401,
contentType: 'application/json',
body: JSON.stringify({ detail: 'Invalid credentials' }),
});
});
// Fill and submit form
await page.getByLabel(/email/i).fill('test@example.com');
await page.getByLabel(/password/i).fill('wrongpassword');
await page.getByRole('button', { name: /sign in/i }).click();
// Check for error message
await expect(page.getByText(/invalid credentials/i)).toBeVisible();
// Should still be on login page
await expect(page).toHaveURL(/.*\/login/);
});
test('should successfully login with valid credentials', async ({ page }) => {
await page.goto('/login');
// Mock successful login response
await page.route('**/api/auth/login', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
access_token: 'mock-jwt-token',
token_type: 'bearer',
user: {
id: '123e4567-e89b-12d3-a456-426614174000',
username: 'testuser',
email: 'test@example.com',
full_name: 'Test User',
role: 'user',
is_active: true,
is_superuser: false,
is_verified: true,
},
}),
});
});
// Mock the /me endpoint for authenticated user
await page.route('**/api/auth/me', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
id: '123e4567-e89b-12d3-a456-426614174000',
username: 'testuser',
email: 'test@example.com',
full_name: 'Test User',
role: 'user',
is_active: true,
is_superuser: false,
is_verified: true,
}),
});
});
// Fill and submit form
await page.getByLabel(/email/i).fill('test@example.com');
await page.getByLabel(/password/i).fill('password123');
await page.getByRole('button', { name: /sign in/i }).click();
// Should redirect to dashboard
await expect(page).toHaveURL(/.*\/dashboard/);
// Check that user is logged in (user menu should be visible)
await expect(page.getByText('Test User')).toBeVisible();
});
test('should toggle password visibility', async ({ page }) => {
await page.goto('/login');
const passwordInput = page.getByLabel(/password/i);
const toggleButton = page.getByRole('button', { name: /toggle password visibility/i });
// Initially password should be hidden
await expect(passwordInput).toHaveAttribute('type', 'password');
// Click toggle to show password
await toggleButton.click();
await expect(passwordInput).toHaveAttribute('type', 'text');
// Click toggle again to hide password
await toggleButton.click();
await expect(passwordInput).toHaveAttribute('type', 'password');
});
test('should logout successfully', async ({ page }) => {
// First login
await page.goto('/login');
// Mock successful login
await page.route('**/api/auth/login', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
access_token: 'mock-jwt-token',
token_type: 'bearer',
user: {
id: '123e4567-e89b-12d3-a456-426614174000',
username: 'testuser',
email: 'test@example.com',
full_name: 'Test User',
},
}),
});
});
await page.getByLabel(/email/i).fill('test@example.com');
await page.getByLabel(/password/i).fill('password123');
await page.getByRole('button', { name: /sign in/i }).click();
// Wait for dashboard
await expect(page).toHaveURL(/.*\/dashboard/);
// Click logout
await page.getByRole('button', { name: /logout/i }).click();
// Should redirect to login page
await expect(page).toHaveURL(/.*\/login/);
});
});