Files
Momento/memento-note/tests/search/non-regression.spec.ts
Sepehr Ramezani e4d4e23dc7 chore: clean up repo for public release
- Remove BMAD framework, IDE configs, dev screenshots, test files,
  internal docs, and backup files
- Rename keep-notes/ to memento-note/
- Update all references from keep-notes to memento-note
- Add Apache 2.0 license with Commons Clause (non-commercial restriction)
- Add clean .gitignore and .env.docker.example
2026-04-20 22:48:06 +02:00

144 lines
4.7 KiB
TypeScript

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);
});
});