- src/hooks/query-keys.ts - tests/e2e/registration.spec.ts - tests/e2e/subscription.spec.ts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
201 lines
7.6 KiB
TypeScript
201 lines
7.6 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { Page } from '@playwright/test';
|
|
|
|
test.describe('Registration Flow', () => {
|
|
let page: Page;
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
page = page;
|
|
});
|
|
|
|
test('should display registration page', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Check page title
|
|
await expect(page).toHaveTitle(/Register/);
|
|
|
|
// Check form elements
|
|
await expect(page.locator('input[name="email"]')).toBeVisible();
|
|
await expect(page.locator('input[name="password"]')).toBeVisible();
|
|
await expect(page.locator('input[name="confirmPassword"]')).toBeVisible();
|
|
await expect(page.locator('input[name="firstName"]')).toBeVisible();
|
|
await expect(page.locator('input[name="lastName"]')).toBeVisible();
|
|
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
|
});
|
|
|
|
test('should show validation errors for invalid data', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Submit empty form
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
// Check for validation errors
|
|
await expect(page.locator('text=Email is required')).toBeVisible();
|
|
await expect(page.locator('text=Password is required')).toBeVisible();
|
|
await expect(page.locator('text=First name is required')).toBeVisible();
|
|
await page.locator('text=Last name is required')).toBeVisible();
|
|
});
|
|
|
|
test('should validate email format', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Enter invalid email
|
|
await page.locator('input[name="email"]').fill('invalid-email');
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
await expect(page.locator('text=Please enter a valid email address')).toBeVisible();
|
|
});
|
|
|
|
test('should validate password matching', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Enter mismatched passwords
|
|
await page.locator('input[name="password"]').fill('password123');
|
|
await page.locator('input[name="confirmPassword"]').fill('password456');
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
await expect(page.locator('text=Passwords do not match')).toBeVisible();
|
|
});
|
|
|
|
test('should register new user successfully', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Fill form with valid data
|
|
const userData = {
|
|
firstName: 'John',
|
|
lastName: 'Doe',
|
|
email: `john.doe.${Date.now()}@example.com`,
|
|
password: 'Password123!',
|
|
confirmPassword: 'Password123!',
|
|
};
|
|
|
|
await page.locator('input[name="firstName"]').fill(userData.firstName);
|
|
await page.locator('input[name="lastName"]').fill(userData.lastName);
|
|
await page.locator('input[name="email"]').fill(userData.email);
|
|
await page.locator('input[name="password"]').fill(userData.password);
|
|
await page.locator('input[name="confirmPassword"]').fill(userData.confirmPassword);
|
|
|
|
// Submit form
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
// Should redirect to email verification page
|
|
await expect(page).toHaveURL(/verify-email/);
|
|
|
|
// Should show success message
|
|
await expect(page.locator('text=Registration successful')).toBeVisible();
|
|
});
|
|
|
|
test('should handle email verification', async () => {
|
|
// Navigate to verification page with token
|
|
const verificationToken = 'test-verification-token';
|
|
await page.goto(`/verify-email?token=${verificationToken}`);
|
|
|
|
// Check verification form
|
|
await expect(page.locator('input[name="token"]')).toHaveValue(verificationToken);
|
|
await expect(page.locator('button[type="submit"]')).toBeVisible();
|
|
|
|
// Submit verification
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
// Should redirect to dashboard
|
|
await expect(page).toHaveURL(/dashboard/);
|
|
|
|
// Should show welcome message
|
|
await expect(page.locator('text=Welcome to your account')).toBeVisible();
|
|
});
|
|
|
|
test('should handle expired verification token', async () => {
|
|
const expiredToken = 'expired-token-123';
|
|
await page.goto(`/verify-email?token=${expiredToken}`);
|
|
|
|
// Should show error message
|
|
await expect(page.locator('text=Verification link has expired')).toBeVisible();
|
|
|
|
// Should show resend option
|
|
await expect(page.locator('button:has-text("Resend verification")')).toBeVisible();
|
|
});
|
|
|
|
test('should resend verification email', async () => {
|
|
await page.goto('/verify-email?token=expired');
|
|
|
|
// Click resend button
|
|
await page.locator('button:has-text("Resend verification")').click();
|
|
|
|
// Should show success message
|
|
await expect(page.locator('text=Verification email sent')).toBeVisible();
|
|
|
|
// Check that original email field is pre-filled
|
|
await expect(page.locator('input[name="email"]')).toBeVisible();
|
|
});
|
|
|
|
test('should prevent registration with existing email', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Try to register with existing email
|
|
await page.locator('input[name="firstName"]').fill('Jane');
|
|
await page.locator('input[name="lastName"]').fill('Smith');
|
|
await page.locator('input[name="email"]').fill('existing@example.com');
|
|
await page.locator('input[name="password"]').fill('Password123!');
|
|
await page.locator('input[name="confirmPassword"]').fill('Password123!');
|
|
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
// Should show error message
|
|
await expect(page.locator('text=An account with this email already exists')).toBeVisible();
|
|
});
|
|
|
|
test('should handle registration with weak password', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Try to register with weak password
|
|
await page.locator('input[name="firstName"]').fill('Test');
|
|
await page.locator('input[name="lastName"]').fill('User');
|
|
await page.locator('input[name="email"]').fill(`test.${Date.now()}@example.com`);
|
|
await page.locator('input[name="password"]').fill('123');
|
|
await page.locator('input[name="confirmPassword"]').fill('123');
|
|
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
// Should show password requirements
|
|
await expect(page.locator('text=Password must be at least 8 characters')).toBeVisible();
|
|
await expect(page.locator('text=Password must contain at least one uppercase letter')).toBeVisible();
|
|
await expect(page.locator('text=Password must contain at least one number')).toBeVisible();
|
|
});
|
|
|
|
test('should handle network errors gracefully', async () => {
|
|
// Mock network error
|
|
await page.route('/api/auth/register', route => route.abort('failed'));
|
|
|
|
await page.goto('/register');
|
|
|
|
// Fill form
|
|
await page.locator('input[name="firstName"]').fill('Test');
|
|
await page.locator('input[name="lastName"]').fill('User');
|
|
await page.locator('input[name="email"]').fill(`test.${Date.now()}@example.com`);
|
|
await page.locator('input[name="password"]').fill('Password123!');
|
|
await page.locator('input[name="confirmPassword"]').fill('Password123!');
|
|
|
|
// Submit form
|
|
await page.locator('button[type="submit"]').click();
|
|
|
|
// Should show network error message
|
|
await expect(page.locator('text=Network error occurred. Please try again.')).toBeVisible();
|
|
});
|
|
|
|
test('should be accessible', async () => {
|
|
await page.goto('/register');
|
|
|
|
// Check accessibility
|
|
const accessibilityScan = await page.accessibility.snapshot();
|
|
expect(accessibilityScan).toHaveNoViolations();
|
|
|
|
// Check keyboard navigation
|
|
await page.keyboard.press('Tab');
|
|
await expect(page.locator('input[name="email"]')).toBeFocused();
|
|
|
|
// Check form labels
|
|
await expect(page.locator('label:has-text("Email Address")')).toBeVisible();
|
|
await expect(page.locator('label:has-text("Password")')).toBeVisible();
|
|
});
|
|
});
|