Readur/frontend/e2e/auth.spec.ts

112 lines
4.0 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { TEST_USERS, TIMEOUTS } from './utils/test-data';
import { TestHelpers } from './utils/test-helpers';
test.describe('Authentication', () => {
let helpers: TestHelpers;
test.beforeEach(async ({ page }) => {
helpers = new TestHelpers(page);
});
test('should display login form on initial visit', async ({ page }) => {
await page.goto('/');
// Check for login form elements using Material-UI structure
await expect(page.locator('input[name="username"]')).toBeVisible();
await expect(page.locator('input[name="password"]')).toBeVisible();
await expect(page.locator('button[type="submit"]')).toBeVisible();
});
test('should login with valid credentials', async ({ page }) => {
await page.goto('/');
// Fill login form with demo credentials
await page.fill('input[name="username"]', 'admin');
await page.fill('input[name="password"]', 'readur2024');
// Wait for login API call
const loginResponse = helpers.waitForApiCall('/auth/login');
await page.click('button[type="submit"]');
// Verify login was successful
await loginResponse;
// Should redirect to dashboard or main page
await page.waitForURL(/\/dashboard|\//, { timeout: TIMEOUTS.medium });
// Verify we're no longer on login page
await expect(page.locator('input[name="username"]')).not.toBeVisible();
});
test('should show error with invalid credentials', async ({ page }) => {
await page.goto('/');
await page.fill('input[name="username"]', 'invaliduser');
await page.fill('input[name="password"]', 'wrongpassword');
await page.click('button[type="submit"]');
// Should show error message (Material-UI Alert)
await expect(page.locator('.MuiAlert-root, [role="alert"]')).toBeVisible({ timeout: TIMEOUTS.short });
// Should remain on login page
await expect(page.locator('input[name="username"]')).toBeVisible();
});
test('should logout successfully', async ({ page }) => {
// First login
await page.goto('/');
await page.fill('input[name="username"]', 'admin');
await page.fill('input[name="password"]', 'readur2024');
await page.click('button[type="submit"]');
await page.waitForURL(/\/dashboard|\//, { timeout: TIMEOUTS.medium });
// Find and click logout button
const logoutButton = page.locator('button:has-text("Logout"), [data-testid="logout"]');
if (await logoutButton.isVisible()) {
await logoutButton.click();
} else {
// Try menu-based logout
await page.click('[data-testid="user-menu"], .user-menu, button:has([data-testid="user-avatar"])');
await page.click('button:has-text("Logout"), [data-testid="logout"]');
}
// Should redirect back to login
await page.waitForURL(/\/login|\//, { timeout: TIMEOUTS.medium });
await expect(page.locator('input[name="username"]')).toBeVisible();
});
test('should persist session on page reload', async ({ page }) => {
// Login first
await page.goto('/');
await page.fill('input[name="username"]', 'admin');
await page.fill('input[name="password"]', 'readur2024');
await page.click('button[type="submit"]');
await page.waitForURL(/\/dashboard|\//, { timeout: TIMEOUTS.medium });
// Reload the page
await page.reload();
// Should still be logged in
await expect(page.locator('input[name="username"]')).not.toBeVisible();
});
test('should validate required fields', async ({ page }) => {
await page.goto('/');
// Try to submit without filling fields
await page.click('button[type="submit"]');
// Should show validation errors or prevent submission
const usernameInput = page.locator('input[name="username"]');
const passwordInput = page.locator('input[name="password"]');
// Check for HTML5 validation or custom validation messages
await expect(usernameInput).toBeVisible();
await expect(passwordInput).toBeVisible();
});
});