Files
ProjectE/e2e/auth.spec.ts
T
mbatchelder 8f55626e03 refactor: migrate to monorepo structure with Docker, PocketBase, and e2e tests
- Reorganize into apps/, packages/, docs/, e2e/, pocketbase/ directories
- Add Dockerfiles for web, worker, and PocketBase services
- Add docker-compose.yml for local orchestration
- Add turbo.json for monorepo task management
- Add Playwright e2e test infrastructure
- Add PocketBase backend with migrations
- Remove Vite/Next.js/ESLint/PostCSS config files
- Update package.json with workspace dependencies
- Add .env.example and .dockerignore
2026-07-16 06:19:58 -04:00

106 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
import { login, logout, goToLogin } from './helpers/auth';
import { TEST_USER, INVALID_USER } from './helpers/fixtures';
test.describe('Authentication Flow', () => {
test.describe('Login', () => {
test('should login with valid credentials and redirect to dashboard', async ({ page }) => {
await goToLogin(page);
// Verify login page loaded
await expect(page.getByRole('heading', { name: /project e/i })).toBeVisible();
await expect(page.getByRole('button', { name: /sign in/i })).toBeVisible();
// Fill in credentials
await page.getByLabel('Email').fill(TEST_USER.email);
await page.getByLabel('Password').fill(TEST_USER.password);
await page.getByRole('button', { name: /sign in/i }).click();
// Should redirect to dashboard
await page.waitForURL('**/dashboard', { timeout: 15_000 });
await expect(page).toHaveURL(/\/dashboard/);
// Dashboard should be visible
await expect(page.getByRole('heading', { name: /dashboard/i })).toBeVisible();
});
test('should show error with invalid credentials', async ({ page }) => {
await goToLogin(page);
await page.getByLabel('Email').fill(INVALID_USER.email);
await page.getByLabel('Password').fill(INVALID_USER.password);
await page.getByRole('button', { name: /sign in/i }).click();
// Should still be on login page
await expect(page).toHaveURL(/\/login/);
// Should show error message (toast or inline)
// The app uses sonner toasts for errors
await expect(
page.getByText(/login failed|invalid/i),
).toBeVisible({ timeout: 10_000 });
});
test('should prevent submitting empty form', async ({ page }) => {
await goToLogin(page);
const submitButton = page.getByRole('button', { name: /sign in/i });
await expect(submitButton).toBeVisible();
// HTML5 required attribute should prevent submission
// The email field is required
await page.getByLabel('Password').fill('somepassword');
await submitButton.click();
// Should stay on login page (HTML5 validation prevents submit)
await expect(page).toHaveURL(/\/login/);
});
});
test.describe('Logout', () => {
test('should logout and redirect to login page', async ({ page }) => {
// First login
await login(page);
await expect(page).toHaveURL(/\/dashboard/);
// Clear cookies to simulate logout
await logout(page);
// Navigate to dashboard should redirect to login
await page.goto('/dashboard');
await page.waitForURL('**/login', { timeout: 10_000 });
await expect(page).toHaveURL(/\/login/);
});
});
test.describe('Session persistence', () => {
test('should stay logged in after page refresh', async ({ page }) => {
await login(page);
await expect(page).toHaveURL(/\/dashboard/);
// Refresh the page
await page.reload();
// Should still be on dashboard
await expect(page).toHaveURL(/\/dashboard/);
await expect(page.getByRole('heading', { name: /dashboard/i })).toBeVisible();
});
});
test.describe('Protected routes', () => {
test('should redirect unauthenticated users from dashboard to login', async ({ page }) => {
await logout(page);
await page.goto('/dashboard');
await page.waitForURL('**/login', { timeout: 10_000 });
await expect(page).toHaveURL(/\/login/);
});
test('should redirect unauthenticated users from tasks to login', async ({ page }) => {
await logout(page);
await page.goto('/tasks');
await page.waitForURL('**/login', { timeout: 10_000 });
await expect(page).toHaveURL(/\/login/);
});
});
});