- Added 'onDelete' and 'onNotes' support to TaskItem. - Implemented hover actions (Delete and Notes icons) for tasks. - Added Notes Modal for editing task markdown content. - Simplified navigation animation to remove blank flash (single-phase slide-in). - Fixed syntax error in updateTask function. - Updated styles for modal and task actions.
231 lines
6.5 KiB
TypeScript
231 lines
6.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Login Page Debug Test', () => {
|
|
test('should load the login page correctly', async ({ page }) => {
|
|
await page.goto('http://localhost:3000/auth/login');
|
|
|
|
// Check page title and heading
|
|
await expect(page).toHaveTitle(/Weekly To Do List/);
|
|
await expect(page.locator('h1')).toContainText('Weekly To Do List');
|
|
await expect(page.locator('p:has-text("Sign in to your account")')).toBeVisible();
|
|
|
|
// Check for Tailwind CSS classes in main container
|
|
const mainContainer = page.locator('div.min-h-screen.bg-gray-50');
|
|
await expect(mainContainer).toBeVisible();
|
|
|
|
// Check for form elements
|
|
const form = page.locator('form');
|
|
await expect(form).toBeVisible();
|
|
|
|
// Check for email input field
|
|
const emailInput = page.locator('#email-address');
|
|
await expect(emailInput).toBeVisible();
|
|
await expect(emailInput).toHaveAttribute('type', 'email');
|
|
await expect(emailInput).toHaveAttribute('placeholder', 'Email address');
|
|
|
|
// Check for password input field
|
|
const passwordInput = page.locator('#password');
|
|
await expect(passwordInput).toBeVisible();
|
|
await expect(passwordInput).toHaveAttribute('type', 'password');
|
|
await expect(passwordInput).toHaveAttribute('placeholder', 'Password');
|
|
|
|
// Check for submit button
|
|
const submitButton = page.locator('button[type="submit"]');
|
|
await expect(submitButton).toBeVisible();
|
|
await expect(submitButton).toContainText('Sign in');
|
|
|
|
// Check for links
|
|
await expect(page.locator('a:has-text("Don\'t have an account?")')).toBeVisible();
|
|
await expect(page.locator('a:has-text("Forgot your password?")')).toBeVisible();
|
|
|
|
// Check for Tailwind classes in form container
|
|
const formContainer = page.locator('div.max-w-md.w-full.space-y-8.bg-white.rounded-xl.shadow-lg.p-8');
|
|
await expect(formContainer).toBeVisible();
|
|
});
|
|
|
|
test('should have Tailwind CSS applied correctly', async ({ page }) => {
|
|
await page.goto('http://localhost:3000/auth/login');
|
|
|
|
// Check for various Tailwind utility classes
|
|
const expectedClasses = [
|
|
'min-h-screen',
|
|
'bg-gray-50',
|
|
'flex',
|
|
'flex-col',
|
|
'items-center',
|
|
'justify-center',
|
|
'py-12',
|
|
'px-4',
|
|
'sm:px-6',
|
|
'lg:px-8',
|
|
'w-full',
|
|
'max-w-md',
|
|
'text-center',
|
|
'mb-8',
|
|
'text-3xl',
|
|
'font-bold',
|
|
'text-gray-900',
|
|
'mt-2',
|
|
'text-gray-600',
|
|
'flex',
|
|
'items-center',
|
|
'justify-center',
|
|
'rounded-full',
|
|
'bg-blue-100',
|
|
'h-16',
|
|
'w-16',
|
|
'text-blue-600',
|
|
'h-8',
|
|
'w-8',
|
|
'mt-2',
|
|
'text-3xl',
|
|
'font-extrabold',
|
|
'text-gray-900',
|
|
'mt-2',
|
|
'text-sm',
|
|
'text-gray-600',
|
|
'rounded-md',
|
|
'bg-red-50',
|
|
'p-4',
|
|
'border',
|
|
'border-red-200',
|
|
'flex',
|
|
'h-5',
|
|
'w-5',
|
|
'text-red-400',
|
|
'text-sm',
|
|
'text-red-700',
|
|
'sr-only',
|
|
'block',
|
|
'text-sm',
|
|
'font-medium',
|
|
'text-gray-700',
|
|
'mb-1',
|
|
'relative',
|
|
'pl-3',
|
|
'flex',
|
|
'items-center',
|
|
'pointer-events-none',
|
|
'h-5',
|
|
'w-5',
|
|
'text-gray-400',
|
|
'appearance-none',
|
|
'rounded-md',
|
|
'relative',
|
|
'block',
|
|
'pl-10',
|
|
'px-3',
|
|
'py-3',
|
|
'border',
|
|
'border-gray-300',
|
|
'placeholder-gray-500',
|
|
'text-gray-900',
|
|
'focus:outline-none',
|
|
'focus:ring-2',
|
|
'focus:ring-blue-500',
|
|
'focus:border-blue-500',
|
|
'sm:text-sm',
|
|
'absolute',
|
|
'inset-y-0',
|
|
'left-0',
|
|
'pr-3',
|
|
'flex',
|
|
'items-center',
|
|
'text-gray-500',
|
|
'hover:text-gray-700',
|
|
'h-5',
|
|
'w-5',
|
|
'text-gray-400',
|
|
'mt-1',
|
|
'text-xs',
|
|
'text-gray-500',
|
|
'group',
|
|
'w-full',
|
|
'flex',
|
|
'justify-center',
|
|
'py-3',
|
|
'px-4',
|
|
'border',
|
|
'border-transparent',
|
|
'text-sm',
|
|
'font-medium',
|
|
'rounded-md',
|
|
'text-white',
|
|
'bg-blue-600',
|
|
'hover:bg-blue-700',
|
|
'focus:outline-none',
|
|
'focus:ring-2',
|
|
'focus:ring-offset-2',
|
|
'focus:ring-blue-500',
|
|
'disabled:opacity-50',
|
|
'transition-colors',
|
|
'duration-200',
|
|
'animate-spin',
|
|
'h-4',
|
|
'w-4',
|
|
'text-white',
|
|
'flex',
|
|
'items-center',
|
|
'text-xs',
|
|
'font-medium',
|
|
'text-blue-600',
|
|
'hover:text-blue-500',
|
|
'text-center',
|
|
'text-sm',
|
|
'text-gray-600'
|
|
];
|
|
|
|
// Check that the page contains at least one element with Tailwind class
|
|
const bodyElement = page.locator('body');
|
|
const bodyClasses = await bodyElement.getAttribute('class');
|
|
expect(bodyClasses).toBeTruthy();
|
|
|
|
// Check for some specific Tailwind classes that should be present
|
|
expect(bodyClasses).toContain('min-h-screen');
|
|
expect(bodyClasses).toContain('bg-gray-50');
|
|
|
|
// Check that the form has appropriate Tailwind classes
|
|
const formElement = page.locator('form');
|
|
const formClasses = await formElement.getAttribute('class');
|
|
expect(formClasses).toContain('space-y-6');
|
|
|
|
// Check that inputs have Tailwind classes
|
|
const inputElement = page.locator('#email-address');
|
|
const inputClasses = await inputElement.getAttribute('class');
|
|
expect(inputClasses).toContain('rounded-md');
|
|
expect(inputClasses).toContain('border');
|
|
expect(inputClasses).toContain('focus:ring-blue-500');
|
|
});
|
|
|
|
test('should validate form submission with empty fields', async ({ page }) => {
|
|
await page.goto('http://localhost:3000/auth/login');
|
|
|
|
// Try submitting with empty fields
|
|
await page.click('button[type="submit"]');
|
|
|
|
// Should still be on the same page and show validation error
|
|
await expect(page).toHaveURL('http://localhost:3000/auth/login');
|
|
});
|
|
|
|
test('should have working password visibility toggle', async ({ page }) => {
|
|
await page.goto('http://localhost:3000/auth/login');
|
|
|
|
const passwordInput = page.locator('#password');
|
|
const toggleButton = page.locator('button[aria-label*="toggle"]');
|
|
|
|
// Initially should be password type
|
|
await expect(passwordInput).toHaveAttribute('type', 'password');
|
|
|
|
// Click toggle button
|
|
await toggleButton.click();
|
|
|
|
// Should switch to text type
|
|
await expect(passwordInput).toHaveAttribute('type', 'text');
|
|
|
|
// Click again to toggle back
|
|
await toggleButton.click();
|
|
|
|
// Should switch back to password type
|
|
await expect(passwordInput).toHaveAttribute('type', 'password');
|
|
});
|
|
}); |