workspace/projects/gamilit/apps/frontend/e2e/auth.spec.ts
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

166 lines
5.5 KiB
TypeScript

import { test, expect } from '@playwright/test';
/**
* Authentication E2E Tests
*
* Critical user flow: Login → Dashboard
*/
test.describe('Authentication Flow', () => {
test.beforeEach(async ({ page }) => {
// Navigate to the app
await page.goto('/');
});
test('should display login page', async ({ page }) => {
// Check that login form is visible
await expect(page.locator('form')).toBeVisible();
await expect(page.getByRole('heading', { name: /iniciar sesión|login/i })).toBeVisible();
// Check for email and password fields
await expect(page.getByLabel(/email|correo/i)).toBeVisible();
await expect(page.getByLabel(/contraseña|password/i)).toBeVisible();
// Check for submit button
await expect(page.getByRole('button', { name: /iniciar sesión|login/i })).toBeVisible();
});
test('should show validation errors with empty form', async ({ page }) => {
// Click login button without filling form
await page.getByRole('button', { name: /iniciar sesión|login/i }).click();
// Should show validation errors
await expect(page.locator('text=/requerido|required|obligatorio/i')).toBeVisible();
});
test('should show error with invalid credentials', async ({ page }) => {
// Fill form with invalid credentials
await page.getByLabel(/email|correo/i).fill('invalid@example.com');
await page.getByLabel(/contraseña|password/i).fill('wrongpassword');
// Submit form
await page.getByRole('button', { name: /iniciar sesión|login/i }).click();
// Should show error message
// Wait for error message (may take a few seconds for API response)
await expect(
page.locator('text=/credenciales inválidas|invalid credentials|error/i'),
).toBeVisible({ timeout: 5000 });
});
test('should navigate to registration page', async ({ page }) => {
// Click on register link
await page.getByRole('link', { name: /registrarse|register|crear cuenta/i }).click();
// Should be on registration page
await expect(page).toHaveURL(/\/register/);
await expect(page.getByRole('heading', { name: /registrar|register/i })).toBeVisible();
});
test.skip('should successfully login with valid credentials', async ({ page }) => {
// NOTE: This test requires a test user in the database
// Skip for now until test data setup is ready
const testEmail = 'test@example.com';
const testPassword = 'Test123!';
// Fill login form
await page.getByLabel(/email|correo/i).fill(testEmail);
await page.getByLabel(/contraseña|password/i).fill(testPassword);
// Submit form
await page.getByRole('button', { name: /iniciar sesión|login/i }).click();
// Should redirect to dashboard after successful login
await expect(page).toHaveURL(/\/dashboard/, { timeout: 10000 });
// Should display user-specific content
await expect(page.locator('text=/bienvenido|welcome/i')).toBeVisible();
});
test('should have password visibility toggle', async ({ page }) => {
const passwordInput = page.getByLabel(/contraseña|password/i);
// Password should be hidden by default
await expect(passwordInput).toHaveAttribute('type', 'password');
// Click toggle button (usually an eye icon)
const toggleButton = page
.locator('button[type="button"]')
.filter({
has: page.locator('svg'), // Icon button
})
.first();
if (await toggleButton.isVisible()) {
await toggleButton.click();
// Password should now be visible
await expect(passwordInput).toHaveAttribute('type', 'text');
}
});
});
test.describe('Registration Flow', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/register');
});
test('should display registration form', async ({ page }) => {
await expect(page.getByRole('heading', { name: /registrar|register/i })).toBeVisible();
// Check for required registration fields
await expect(page.getByLabel(/nombre|name|first name/i)).toBeVisible();
await expect(page.getByLabel(/email|correo/i)).toBeVisible();
await expect(page.getByLabel(/contraseña|password/i)).toBeVisible();
});
test('should validate password strength', async ({ page }) => {
const passwordInput = page.getByLabel(/contraseña|password/i).first();
// Type weak password
await passwordInput.fill('123');
// Should show password strength indicator or validation message
// This depends on your implementation
await expect(page.locator('text=/débil|weak|contraseña debe|password must/i')).toBeVisible({
timeout: 3000,
});
});
test('should validate email format', async ({ page }) => {
const emailInput = page.getByLabel(/email|correo/i);
// Type invalid email
await emailInput.fill('invalid-email');
await emailInput.blur(); // Trigger validation
// Should show validation error
await expect(page.locator('text=/email inválido|invalid email|formato/i')).toBeVisible({
timeout: 3000,
});
});
});
test.describe('Session Management', () => {
test('should handle session timeout', async ({ page }) => {
await page.goto('/');
// This test would need to:
// 1. Login
// 2. Wait for session to expire (or manipulate token)
// 3. Try to access protected route
// 4. Verify redirect to login
// Skipping for now as it requires complex setup
test.skip();
});
test('should persist session across page reloads', async ({ page: _page }) => {
// This test would verify that after login,
// refreshing the page keeps the user logged in
test.skip();
});
});