Verifies that searching "Writing" in Quick Open shows the exact title match first, followed by prefix matches. Also adds Refactoring test entries to mock data and demo vault. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
import { sendShortcut } from './helpers'
|
|
|
|
const QUICK_OPEN_INPUT = 'input[placeholder="Search notes..."]'
|
|
|
|
async function openQuickOpen(page: import('@playwright/test').Page) {
|
|
await page.locator('body').click()
|
|
await sendShortcut(page, 'p', ['Control'])
|
|
await expect(page.locator(QUICK_OPEN_INPUT)).toBeVisible()
|
|
}
|
|
|
|
/**
|
|
* Get the title text of the first (selected) search result in the Quick Open palette.
|
|
* The selected item has `bg-accent` class, and the title is in a nested `.truncate` span.
|
|
*/
|
|
async function getFirstResultTitle(page: import('@playwright/test').Page): Promise<string> {
|
|
// The selected result row contains the title in a span.truncate
|
|
const titleSpan = page.locator('[class*="bg-accent"] span.truncate')
|
|
await titleSpan.first().waitFor({ timeout: 3000 })
|
|
return (await titleSpan.first().textContent()) ?? ''
|
|
}
|
|
|
|
test.describe('Exact match search ranking', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/')
|
|
await page.waitForLoadState('networkidle')
|
|
})
|
|
|
|
test('exact title match appears as first result', async ({ page }) => {
|
|
await openQuickOpen(page)
|
|
// "Writing" is a Topic note in the demo vault; other notes have "Writing" as a prefix
|
|
await page.locator(QUICK_OPEN_INPUT).fill('Writing')
|
|
await page.waitForTimeout(300)
|
|
|
|
const firstTitle = await getFirstResultTitle(page)
|
|
expect(firstTitle).toBe('Writing')
|
|
})
|
|
|
|
test('case-insensitive exact match appears first', async ({ page }) => {
|
|
await openQuickOpen(page)
|
|
await page.locator(QUICK_OPEN_INPUT).fill('writing')
|
|
await page.waitForTimeout(300)
|
|
|
|
const firstTitle = await getFirstResultTitle(page)
|
|
expect(firstTitle).toBe('Writing')
|
|
})
|
|
|
|
test('partial matches still appear below exact match', async ({ page }) => {
|
|
await openQuickOpen(page)
|
|
await page.locator(QUICK_OPEN_INPUT).fill('Writing')
|
|
await page.waitForTimeout(300)
|
|
|
|
// Should have multiple results (exact + prefix/fuzzy matches)
|
|
const resultRows = page.locator('[class*="cursor-pointer"][class*="items-center"]')
|
|
const count = await resultRows.count()
|
|
expect(count).toBeGreaterThan(1)
|
|
|
|
// First result is the exact match
|
|
const firstTitle = await getFirstResultTitle(page)
|
|
expect(firstTitle).toBe('Writing')
|
|
})
|
|
|
|
test('arrow keys navigate search results past the exact match', async ({ page }) => {
|
|
await openQuickOpen(page)
|
|
await page.locator(QUICK_OPEN_INPUT).fill('Writing')
|
|
await page.waitForTimeout(300)
|
|
|
|
// First result should be selected (exact match)
|
|
const firstTitle = await getFirstResultTitle(page)
|
|
expect(firstTitle).toBe('Writing')
|
|
|
|
// ArrowDown moves to next result (a prefix or fuzzy match)
|
|
await page.keyboard.press('ArrowDown')
|
|
await page.waitForTimeout(100)
|
|
const secondTitle = await getFirstResultTitle(page)
|
|
expect(secondTitle).not.toBe('Writing')
|
|
})
|
|
})
|