import { test, expect } from '@playwright/test'; /** * Non-regression tests for semantic search * These tests ensure that increasing the threshold from 0.40 to 0.65 * doesn't lose valid positive matches */ test.describe('Search Non-Regression Tests', () => { test.beforeEach(async ({ page }) => { await page.goto('http://localhost:3000'); await page.waitForLoadState('networkidle'); }); test('should find notes with exact keyword matches', async ({ page }) => { const searchInput = page.locator('input[placeholder*="Search"]'); await searchInput.fill('test'); await page.waitForTimeout(500); const results = await page.locator('.note-card').count(); // Even with higher semantic threshold, exact keyword matches should always appear if (results > 0) { const titles = await page.locator('.note-card .note-title').allTextContents(); const hasExactMatch = titles.some(title => title.toLowerCase().includes('test') ); expect(hasExactMatch).toBe(true); } }); test('should find notes with title matches', async ({ page }) => { // Search for something that should be in titles const searchInput = page.locator('input[placeholder*="Search"]'); // Try a generic search term await searchInput.fill('note'); await page.waitForTimeout(500); const results = await page.locator('.note-card'); const count = await results.count(); // Should find results with "note" in them if (count > 0) { const allText = await results.allTextContents(); const hasNote = allText.some(text => text.toLowerCase().includes('note') ); expect(hasNote).toBe(true); } }); test('should handle multi-word queries correctly', async ({ page }) => { const searchInput = page.locator('input[placeholder*="Search"]'); // Multi-word search should work await searchInput.fill('test note'); await page.waitForTimeout(500); // Should not error and should return results const results = await page.locator('.note-card').count(); expect(results).toBeGreaterThanOrEqual(0); }); test('should be case-insensitive', async ({ page }) => { const searchInput = page.locator('input[placeholder*="Search"]'); // Search with uppercase await searchInput.fill('TEST'); await page.waitForTimeout(500); const upperCount = await page.locator('.note-card').count(); // Search with lowercase await searchInput.fill('test'); await page.waitForTimeout(500); const lowerCount = await page.locator('.note-card').count(); // Should return same results expect(upperCount).toBe(lowerCount); }); test('should handle empty search gracefully', async ({ page }) => { const searchInput = page.locator('input[placeholder*="Search"]'); // Empty search should show all notes or handle gracefully await searchInput.fill(''); await page.waitForTimeout(500); // Should not error const results = await page.locator('.note-card').count(); expect(results).toBeGreaterThanOrEqual(0); }); test('should clear search results', async ({ page }) => { const searchInput = page.locator('input[placeholder*="Search"]'); // Search for something await searchInput.fill('temporary search'); await page.waitForTimeout(500); // Clear search await searchInput.fill(''); await page.waitForTimeout(500); // Should return to showing all notes (or initial state) const results = await page.locator('.note-card').count(); expect(results).toBeGreaterThanOrEqual(0); }); }); /** * Unit tests for threshold behavior */ test.describe('Threshold Behavior Unit Tests', () => { test('threshold 0.65 should filter more than 0.40', () => { // Simulate semantic scores const scores = [0.80, 0.65, 0.50, 0.45, 0.40, 0.30, 0.20]; // Old threshold (0.40) const oldThresholdMatches = scores.filter(s => s > 0.40).length; // New threshold (0.65) const newThresholdMatches = scores.filter(s => s > 0.65).length; // New threshold should filter more strictly expect(newThresholdMatches).toBeLessThan(oldThresholdMatches); }); test('threshold 0.65 should keep high-quality matches', () => { const highQualityScores = [0.95, 0.85, 0.75, 0.70, 0.68]; // All high-quality scores should pass the threshold const matches = highQualityScores.filter(s => s > 0.65); expect(matches.length).toBe(highQualityScores.length); }); test('threshold 0.65 should filter low-quality matches', () => { const lowQualityScores = [0.30, 0.40, 0.50, 0.60, 0.64]; // None should pass the 0.65 threshold const matches = lowQualityScores.filter(s => s > 0.65); expect(matches.length).toBe(0); }); });