test: share search helpers and wait for specific result states

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/5412/head
Divyansh Singh 2 weeks ago
parent d1b318dba4
commit 0ee35a902d

@ -16,7 +16,7 @@ describe('local search', () => {
})
try {
await page.locator('.VPNavBarSearchButton').click()
await openSearch()
const loading = page.locator('.search-loading')
const results = page.locator('.results')
@ -49,22 +49,10 @@ describe('local search', () => {
)
test('exclude content from search results', async () => {
await page.locator('.VPNavBarSearchButton').click()
const input = await page.waitForSelector('input#localsearch-input')
await input.type('local')
await searchFor('local')
await waitForSearchResults({ text: 'Local search included', count: 1 })
const searchResults = page.locator('#localsearch-list')
await page.waitForFunction(() => {
const options = [
...document.querySelectorAll('#localsearch-list li[role=option]')
]
return (
options.length === 1 &&
options[0].textContent?.includes('Local search included')
)
})
expect(await searchResults.locator('li[role=option]').count()).toBe(1)
@ -84,21 +72,10 @@ describe('local search', () => {
})
test('resolves $frontmatter expressions in search results', async () => {
await page.locator('.VPNavBarSearchButton').click()
const input = await page.waitForSelector('input#localsearch-input')
await input.fill('Frontmatter Title Resolved')
await searchFor('Frontmatter Title Resolved')
await waitForSearchResults({ text: 'Frontmatter Title Resolved' })
const searchResults = page.locator('#localsearch-list')
await page.waitForFunction(() => {
const options = [
...document.querySelectorAll('#localsearch-list li[role=option]')
]
return options.some((option) =>
option.textContent?.includes('Frontmatter Title Resolved')
)
})
expect(
await searchResults
@ -111,25 +88,11 @@ describe('local search', () => {
})
test('custom tokenize function reaches the client', async () => {
await page.locator('.VPNavBarSearchButton').click()
const input = await page.waitForSelector('input#localsearch-input')
// '#hash-probe' survives as one token only under the custom tokenizer —
// MiniSearch's default one would degrade the query to 'hash'/'probe'
// and miss the index built with the custom tokenizer
await input.type('#hash-probe')
await page.waitForFunction(() => {
const options = [
...document.querySelectorAll('#localsearch-list li[role=option]')
]
return (
options.length === 1 &&
options[0].textContent?.includes('Local search included')
)
})
const input = await searchFor('#hash-probe')
await waitForSearchResults({ text: 'Local search included', count: 1 })
// a fragment of a kept-whole token must not match anything
await input.fill('linked-words')
@ -145,8 +108,7 @@ describe('local search', () => {
]) {
await page.setViewportSize({ width, height: 600 })
await goto('/')
await page.locator('.VPNavBarSearchButton').click()
await page.waitForSelector('input#localsearch-input')
await openSearch()
expect(await page.locator('.VPNavBarHamburger').isVisible()).toBe(
!isDesktop
@ -162,17 +124,9 @@ describe('local search', () => {
test('navigate results with macOS Ctrl shortcuts', async () => {
await page.evaluate(() => document.documentElement.classList.add('mac'))
await page.locator('.VPNavBarSearchButton').click()
const input = await page.waitForSelector('input#localsearch-input')
await input.type('lorem')
await page.waitForFunction(() => {
return (
document.querySelectorAll('#localsearch-list li[role=option]').length >
1
)
})
const input = await searchFor('lorem')
await waitForSearchResults({ minCount: 2 })
expect(await input.getAttribute('aria-activedescendant')).toBe(
'localsearch-item-0'
@ -190,6 +144,43 @@ describe('local search', () => {
})
})
async function openSearch() {
await page.locator('.VPNavBarSearchButton').click()
return page.waitForSelector('input#localsearch-input')
}
// fills the query in one step, so exactly one search runs and the result
// list settles into the state for this query and nothing else
async function searchFor(query: string) {
const input = await openSearch()
await input.fill(query)
return input
}
// waits until the result list matches, so assertions never run against the
// results of an earlier query
function waitForSearchResults(condition: {
/** some result must contain this text */
text?: string
/** exactly this many results */
count?: number
/** at least this many results */
minCount?: number
}) {
return page.waitForFunction(({ text, count, minCount }) => {
const options = [
...document.querySelectorAll('#localsearch-list li[role=option]')
]
return (
(count === undefined || options.length === count) &&
(minCount === undefined || options.length >= minCount) &&
(text === undefined ||
options.some((option) => option.textContent?.includes(text)))
)
}, condition)
}
function pressMacCtrl(key: string) {
return page.evaluate((key) => {
window.dispatchEvent(

Loading…
Cancel
Save