import { test, expect } from '@playwright/test'; test.describe('Note Input - Reminder Dialog', () => { test.beforeEach(async ({ page }) => { await page.goto('/'); // Expand the note input await page.click('input[placeholder="Take a note..."]'); await expect(page.locator('input[placeholder="Title"]')).toBeVisible(); }); test('should open dialog when clicking Bell icon (not prompt)', async ({ page }) => { // Set up listener for prompt dialogs - should NOT appear let promptAppeared = false; page.on('dialog', () => { promptAppeared = true; }); // Click the Bell button const bellButton = page.locator('button:has(svg.lucide-bell)'); await bellButton.click(); // Verify dialog opened (NOT a browser prompt) const dialog = page.locator('[role="dialog"]'); await expect(dialog).toBeVisible(); // Verify dialog title await expect(page.locator('h2:has-text("Set Reminder")')).toBeVisible(); // Verify no prompt appeared expect(promptAppeared).toBe(false); // Verify date and time inputs exist await expect(page.locator('input[type="date"]')).toBeVisible(); await expect(page.locator('input[type="time"]')).toBeVisible(); // Verify buttons await expect(page.locator('button:has-text("Cancel")')).toBeVisible(); await expect(page.locator('button:has-text("Set Reminder")')).toBeVisible(); }); test('should have default values (tomorrow 9am)', async ({ page }) => { // Click Bell await page.click('button:has(svg.lucide-bell)'); // Get tomorrow's date const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const expectedDate = tomorrow.toISOString().split('T')[0]; // Check date input const dateInput = page.locator('input[type="date"]'); await expect(dateInput).toHaveValue(expectedDate); // Check time input const timeInput = page.locator('input[type="time"]'); await expect(timeInput).toHaveValue('09:00'); }); test('should close dialog on Cancel', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); await expect(page.locator('[role="dialog"]')).toBeVisible(); // Click Cancel await page.click('button:has-text("Cancel")'); // Dialog should close await expect(page.locator('[role="dialog"]')).not.toBeVisible(); }); test('should close dialog on X button', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); await expect(page.locator('[role="dialog"]')).toBeVisible(); // Click X button (close button in dialog) const closeButton = page.locator('[role="dialog"] button[data-slot="dialog-close"]'); await closeButton.click(); // Dialog should close await expect(page.locator('[role="dialog"]')).not.toBeVisible(); }); test('should validate empty date/time', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); // Clear date const dateInput = page.locator('input[type="date"]'); await dateInput.fill(''); // Click Set Reminder await page.click('button:has-text("Set Reminder")'); // Should show warning toast (not close dialog) // We look for the toast notification await expect(page.locator('text=Please enter date and time')).toBeVisible(); // Dialog should still be open await expect(page.locator('[role="dialog"]')).toBeVisible(); }); test('should validate past date', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); // Set date to yesterday const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); const pastDate = yesterday.toISOString().split('T')[0]; const dateInput = page.locator('input[type="date"]'); await dateInput.fill(pastDate); // Click Set Reminder await page.click('button:has-text("Set Reminder")'); // Should show error toast await expect(page.locator('text=Reminder must be in the future')).toBeVisible(); // Dialog should still be open await expect(page.locator('[role="dialog"]')).toBeVisible(); }); test('should set reminder successfully with valid date', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); // Set future date (tomorrow already default) const timeInput = page.locator('input[type="time"]'); await timeInput.fill('14:30'); // Click Set Reminder await page.click('button:has-text("Set Reminder")'); // Should show success toast await expect(page.locator('text=/Reminder set for/')).toBeVisible(); // Dialog should close await expect(page.locator('[role="dialog"]')).not.toBeVisible(); }); test('should clear fields after successful reminder', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); // Set and confirm await page.click('button:has-text("Set Reminder")'); // Wait for dialog to close await expect(page.locator('[role="dialog"]')).not.toBeVisible(); // Open again await page.click('button:has(svg.lucide-bell)'); // Should have default values again (tomorrow 9am) const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const expectedDate = tomorrow.toISOString().split('T')[0]; await expect(page.locator('input[type="date"]')).toHaveValue(expectedDate); await expect(page.locator('input[type="time"]')).toHaveValue('09:00'); }); test('should allow custom date and time selection', async ({ page }) => { // Open dialog await page.click('button:has(svg.lucide-bell)'); // Set custom date (next week) const nextWeek = new Date(); nextWeek.setDate(nextWeek.getDate() + 7); const customDate = nextWeek.toISOString().split('T')[0]; const dateInput = page.locator('input[type="date"]'); await dateInput.fill(customDate); // Set custom time const timeInput = page.locator('input[type="time"]'); await timeInput.fill('15:45'); // Submit await page.click('button:has-text("Set Reminder")'); // Should show success with the date/time await expect(page.locator('text=/Reminder set for/')).toBeVisible(); await expect(page.locator('[role="dialog"]')).not.toBeVisible(); }); }); test.describe('Note Editor - Reminder Dialog', () => { test.beforeEach(async ({ page }) => { await page.goto('/'); // Create a test note await page.click('input[placeholder="Take a note..."]'); await page.fill('input[placeholder="Title"]', 'Test Note for Reminder'); await page.fill('textarea[placeholder="Take a note..."]', 'This note will have a reminder'); await page.click('button:has-text("Add")'); await page.waitForTimeout(500); // Open the note for editing await page.click('text=Test Note for Reminder'); await page.waitForTimeout(300); }); test('should open reminder dialog in note editor', async ({ page }) => { // Click the Bell button in note editor const bellButton = page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first(); await bellButton.click(); // Should open a second dialog for reminder await page.waitForTimeout(300); // Verify reminder dialog opened await expect(page.locator('h2:has-text("Set Reminder")')).toBeVisible(); // Verify date and time inputs exist await expect(page.locator('input[type="date"]')).toBeVisible(); await expect(page.locator('input[type="time"]')).toBeVisible(); }); test('should set reminder on existing note', async ({ page }) => { // Click Bell button await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); // Set date and time const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateString = tomorrow.toISOString().split('T')[0]; await page.fill('input[type="date"]', dateString); await page.fill('input[type="time"]', '14:30'); // Click Set Reminder await page.click('button:has-text("Set Reminder")'); // Should show success toast await expect(page.locator('text=/Reminder set for/')).toBeVisible(); // Reminder dialog should close await page.waitForTimeout(300); await expect(page.locator('h2:has-text("Set Reminder")')).not.toBeVisible(); }); test('should show bell button as active when reminder is set', async ({ page }) => { // Set reminder await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateString = tomorrow.toISOString().split('T')[0]; await page.fill('input[type="date"]', dateString); await page.fill('input[type="time"]', '10:00'); await page.click('button:has-text("Set Reminder")'); await page.waitForTimeout(500); // Bell button should have active styling (text-blue-600) const bellButton = page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first(); const className = await bellButton.getAttribute('class'); expect(className).toContain('text-blue-600'); }); test('should allow editing existing reminder', async ({ page }) => { // Set initial reminder await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateString = tomorrow.toISOString().split('T')[0]; await page.fill('input[type="date"]', dateString); await page.fill('input[type="time"]', '10:00'); await page.click('button:has-text("Set Reminder")'); await page.waitForTimeout(500); // Open reminder dialog again await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); // Should show previous values const dateInput = page.locator('input[type="date"]'); const timeInput = page.locator('input[type="time"]'); await expect(dateInput).toHaveValue(dateString); await expect(timeInput).toHaveValue('10:00'); // Change time await timeInput.fill('15:00'); await page.click('button:has-text("Set Reminder")'); await expect(page.locator('text=/Reminder set for/')).toBeVisible(); }); test('should allow removing reminder', async ({ page }) => { // Set reminder first await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateString = tomorrow.toISOString().split('T')[0]; await page.fill('input[type="date"]', dateString); await page.fill('input[type="time"]', '10:00'); await page.click('button:has-text("Set Reminder")'); await page.waitForTimeout(500); // Open reminder dialog again await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); // Should see "Remove Reminder" button await expect(page.locator('button:has-text("Remove Reminder")')).toBeVisible(); // Click Remove Reminder await page.click('button:has-text("Remove Reminder")'); // Should show success toast await expect(page.locator('text=Reminder removed')).toBeVisible(); // Bell button should not be active anymore await page.waitForTimeout(300); const bellButton = page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first(); const className = await bellButton.getAttribute('class'); expect(className).not.toContain('text-blue-600'); }); test('should persist reminder after saving note', async ({ page }) => { // Set reminder await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateString = tomorrow.toISOString().split('T')[0]; await page.fill('input[type="date"]', dateString); await page.fill('input[type="time"]', '14:00'); await page.click('button:has-text("Set Reminder")'); await page.waitForTimeout(500); // Save the note await page.click('button:has-text("Save")'); await page.waitForTimeout(500); // Reopen the note await page.click('text=Test Note for Reminder'); await page.waitForTimeout(300); // Bell button should still be active const bellButton = page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first(); const className = await bellButton.getAttribute('class'); expect(className).toContain('text-blue-600'); // Open reminder dialog to verify values await bellButton.click(); await page.waitForTimeout(200); const dateInput = page.locator('input[type="date"]'); const timeInput = page.locator('input[type="time"]'); await expect(dateInput).toHaveValue(dateString); await expect(timeInput).toHaveValue('14:00'); }); test('should show bell icon on note card when reminder is set', async ({ page }) => { // Set reminder await page.locator('[role="dialog"]:visible button:has(svg.lucide-bell)').first().click(); await page.waitForTimeout(200); const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateString = tomorrow.toISOString().split('T')[0]; await page.fill('input[type="date"]', dateString); await page.fill('input[type="time"]', '10:00'); await page.click('button:has-text("Set Reminder")'); await page.waitForTimeout(500); // Save and close await page.click('button:has-text("Save")'); await page.waitForTimeout(500); // Check that note card has bell icon const noteCard = page.locator('text=Test Note for Reminder').locator('..'); await expect(noteCard.locator('svg.lucide-bell')).toBeVisible(); }); test.afterEach(async ({ page }) => { // Close any open dialogs const dialogs = page.locator('[role="dialog"]'); const count = await dialogs.count(); for (let i = 0; i < count; i++) { const cancelButton = page.locator('button:has-text("Cancel")').first(); if (await cancelButton.isVisible()) { await cancelButton.click(); await page.waitForTimeout(200); } } // Delete test note try { const testNote = page.locator('text=Test Note for Reminder').first(); if (await testNote.isVisible()) { await testNote.hover(); await page.click('button:has(svg.lucide-more-vertical)').first(); await page.click('text=Delete').first(); // Confirm delete page.once('dialog', dialog => dialog.accept()); await page.waitForTimeout(300); } } catch (e) { // Note might already be deleted } }); });