import { test, expect } from '@playwright/test'; /** * E2E Test: Auto-Labeling Bug Fix (Story 7.1) * * This test verifies that auto-labeling works correctly when creating a new note. * * Acceptance Criteria: * 1. Given a user creates a new note with content * 2. When the note is saved * 3. Then the system should: * - Automatically analyze the note content for relevant labels * - Assign suggested labels to the note * - Display the note in the UI with labels visible * - NOT require a page refresh to see labels */ test.describe('Auto-Labeling Bug Fix', () => { test.beforeEach(async ({ page }) => { // Login await page.goto('/'); await page.waitForURL('**/sign-in', { timeout: 5000 }); // Fill login form await page.fill('input[type="email"]', 'test@example.com'); await page.fill('input[type="password"]', 'password123'); await page.click('button[type="submit"]'); // Wait for navigation to home page await page.waitForURL('/', { timeout: 5000 }); }); test('should auto-label a note about programming', async ({ page }) => { // Create a new note about programming const noteContent = 'Need to learn React and TypeScript for web development'; // Click "New Note" button await page.click('[data-testid="new-note-button"], button:has-text("New Note"), .create-note-btn'); // Wait for note to be created await page.waitForSelector('.note-card, [data-testid^="note-"]', { timeout: 3000 }); // Find the newly created note (first one in the list) const firstNote = page.locator('.note-card, [data-testid^="note-"]').first(); await expect(firstNote).toBeVisible(); // Click on the note to edit it await firstNote.click(); // Wait for note editor to appear await page.waitForSelector('[data-testid="note-editor"], textarea.note-content, .note-editor', { timeout: 3000 }); // Type content about programming const textarea = page.locator('[data-testid="note-editor"] textarea, textarea.note-content, .note-editor textarea'); await textarea.fill(noteContent); // Wait a moment for auto-labeling to process await page.waitForTimeout(1000); // Find labels in the note const labels = page.locator('.label-badge, .tag, [data-testid*="label"]'); // Verify that labels appear (auto-labeling should have assigned them) await expect(labels.first()).toBeVisible({ timeout: 5000 }); // Verify the label text contains relevant keywords (like "code", "development", "programming", etc.) const labelText = await labels.first().textContent(); expect(labelText?.toLowerCase()).toMatch(/code|development|programming|react|typescript|web/); console.log('✓ Auto-labeling applied relevant labels:', labelText); }); test('should auto-label a note about meetings', async ({ page }) => { // Create a note about a meeting const noteContent = 'Team meeting scheduled for tomorrow at 2pm to discuss project roadmap'; // Click "New Note" button await page.click('[data-testid="new-note-button"], button:has-text("New Note"), .create-note-btn'); // Wait for note to be created await page.waitForSelector('.note-card, [data-testid^="note-"]', { timeout: 3000 }); // Find the newly created note const firstNote = page.locator('.note-card, [data-testid^="note-"]').first(); await expect(firstNote).toBeVisible(); // Click on the note to edit it await firstNote.click(); // Wait for note editor await page.waitForSelector('[data-testid="note-editor"], textarea.note-content, .note-editor', { timeout: 3000 }); // Type content about meeting const textarea = page.locator('[data-testid="note-editor"] textarea, textarea.note-content, .note-editor textarea'); await textarea.fill(noteContent); // Wait for auto-labeling await page.waitForTimeout(1000); // Check for labels const labels = page.locator('.label-badge, .tag, [data-testid*="label"]'); await expect(labels.first()).toBeVisible({ timeout: 5000 }); // Verify meeting-related label const labelText = await labels.first().textContent(); expect(labelText?.toLowerCase()).toMatch(/meeting|team|project|roadmap|discussion/); console.log('✓ Auto-labeling applied meeting-related labels:', labelText); }); test('should display labels immediately without page refresh', async ({ page }) => { // This test verifies the critical requirement: labels should be visible WITHOUT refreshing const noteContent = 'Need to buy groceries: milk, bread, eggs, and vegetables'; // Click "New Note" await page.click('[data-testid="new-note-button"], button:has-text("New Note"), .create-note-btn'); // Wait for note creation await page.waitForSelector('.note-card, [data-testid^="note-"]', { timeout: 3000 }); // Click on the note const firstNote = page.locator('.note-card, [data-testid^="note-"]').first(); await firstNote.click(); // Wait for editor await page.waitForSelector('[data-testid="note-editor"], textarea.note-content, .note-editor', { timeout: 3000 }); // Type content const textarea = page.locator('[data-testid="note-editor"] textarea, textarea.note-content, .note-editor textarea'); await textarea.fill(noteContent); // CRITICAL: Wait for labels to appear WITHOUT refreshing const labels = page.locator('.label-badge, .tag, [data-testid*="label"]'); // Labels should appear within 5 seconds (optimistic update + server processing) await expect(labels.first()).toBeVisible({ timeout: 5000 }); console.log('✓ Labels appeared immediately without page refresh'); }); test('should handle auto-labeling failure gracefully', async ({ page }) => { // This test verifies error handling: if auto-labeling fails, the note should still be created const noteContent = 'Test note with very short content'; // Click "New Note" await page.click('[data-testid="new-note-button"], button:has-text("New Note"), .create-note-btn'); // Wait for note creation await page.waitForSelector('.note-card, [data-testid^="note-"]', { timeout: 3000 }); // Click on the note const firstNote = page.locator('.note-card, [data-testid^="note-"]').first(); await firstNote.click(); // Wait for editor await page.waitForSelector('[data-testid="note-editor"], textarea.note-content, .note-editor', { timeout: 3000 }); // Type very short content (may not generate labels) const textarea = page.locator('[data-testid="note-editor"] textarea, textarea.note-content, .note-editor textarea'); await textarea.fill(noteContent); // Wait for processing await page.waitForTimeout(2000); // Note should still be visible even if no labels are assigned await expect(firstNote).toBeVisible(); console.log('✓ Note created successfully even if auto-labeling fails or returns no suggestions'); }); test('should auto-label in notebook context', async ({ page }) => { // Test that auto-labeling uses notebook context for suggestions const noteContent = 'Planning a trip to Japan next month'; // Create a notebook first (if not exists) const notebookExists = await page.locator('.notebook-item:has-text("Travel")').count(); if (notebookExists === 0) { await page.click('[data-testid="create-notebook-button"], button:has-text("Create Notebook")'); await page.fill('input[placeholder*="notebook name"], input[placeholder*="name"]', 'Travel'); await page.click('button:has-text("Create"), button[type="submit"]'); } // Navigate to Travel notebook await page.click('.notebook-item:has-text("Travel")'); // Wait for navigation await page.waitForTimeout(500); // Click "New Note" await page.click('[data-testid="new-note-button"], button:has-text("New Note"), .create-note-btn'); // Wait for note creation await page.waitForSelector('.note-card, [data-testid^="note-"]', { timeout: 3000 }); // Click on the note const firstNote = page.locator('.note-card, [data-testid^="note-"]').first(); await firstNote.click(); // Wait for editor await page.waitForSelector('[data-testid="note-editor"], textarea.note-content, .note-editor', { timeout: 3000 }); // Type travel-related content const textarea = page.locator('[data-testid="note-editor"] textarea, textarea.note-content, .note-editor textarea'); await textarea.fill(noteContent); // Wait for auto-labeling await page.waitForTimeout(1000); // Check for labels (should be travel-related) const labels = page.locator('.label-badge, .tag, [data-testid*="label"]'); const labelCount = await labels.count(); // At least one label should appear (or note should still be visible if no labels) if (labelCount > 0) { const labelText = await labels.first().textContent(); console.log('✓ Auto-labeling in notebook context applied labels:', labelText); } else { console.log('✓ Note created in notebook context (no labels generated for this content)'); } // Note should be visible regardless await expect(firstNote).toBeVisible(); }); });