Readur/frontend/e2e/auth.spec.ts

100 lines
3.7 KiB
TypeScript

import { test, expect, AuthHelper, TEST_CREDENTIALS, TIMEOUTS } from './fixtures/auth';
import { TestHelpers } from './utils/test-helpers';
test.describe('Authentication', () => {
test.beforeEach(async ({ page }) => {
const authHelper = new AuthHelper(page);
await authHelper.ensureLoggedOut();
});
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[type="text"]').first()).toBeVisible();
await expect(page.locator('input[type="password"]').first()).toBeVisible();
await expect(page.locator('button[type="submit"]')).toBeVisible();
});
test('should login with valid credentials', async ({ page }) => {
const authHelper = new AuthHelper(page);
await authHelper.loginAs(TEST_CREDENTIALS.admin);
// Should redirect to dashboard
await page.waitForURL(/.*\/dashboard.*/, { timeout: TIMEOUTS.navigation });
// Verify we're logged in by checking for welcome message
await expect(page.locator('h4:has-text("Welcome back,")')).toBeVisible();
});
test('should show error with invalid credentials', async ({ page }) => {
await page.goto('/');
await page.fill('input[type="text"]', 'invaliduser');
await page.fill('input[type="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.api });
// Should remain on login page
await expect(page.locator('input[type="text"]')).toBeVisible();
});
test.skip('should logout successfully', async ({ page }) => {
const authHelper = new AuthHelper(page);
// First login
await authHelper.loginAs(TEST_CREDENTIALS.admin);
await page.waitForURL(/\/dashboard|\//, { timeout: TIMEOUTS.navigation });
// Find and click profile/account button in the top app bar (has AccountIcon)
const profileButton = page.locator('button:has([data-testid="AccountCircleIcon"])');
await profileButton.click();
// Wait for profile menu to open and click logout
const logoutMenuItem = page.locator('li[role="menuitem"]:has-text("Logout")');
await logoutMenuItem.click();
// Should redirect back to login
await page.waitForURL(/\/login|\//, { timeout: TIMEOUTS.navigation });
await expect(page.locator('input[name="username"]')).toBeVisible();
});
test.skip('should persist session on page reload', async ({ page }) => {
const authHelper = new AuthHelper(page);
// Login first
await authHelper.loginAs(TEST_CREDENTIALS.admin);
await page.waitForURL(/\/dashboard|\//, { timeout: TIMEOUTS.navigation });
// Reload the page
await page.reload();
// Wait for page to load after reload
await page.waitForLoadState('networkidle');
// Should still be logged in (either on dashboard or main page, but not login)
await page.waitForURL(/\/dashboard|\/(?!login)/, { timeout: TIMEOUTS.navigation });
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[type="text"]');
const passwordInput = page.locator('input[type="password"]');
// Check for HTML5 validation or custom validation messages
await expect(usernameInput).toBeVisible();
await expect(passwordInput).toBeVisible();
});
});