Skip to content

Commit a3189c4

Browse files
cdervclaude
andauthored
Add test coverage for search highlight persistence (#14047, #9802) (#14049)
* Add .gitignore for search-highlight test fixture * Add test verifying search highlight listeners register after delay Complements the persistence test by confirming that quarto-hrChanged does clear marks after the 1000ms registration delay elapses. * Add changelog entry for search highlight fix * Add test coverage for search highlight persistence (#14047, #9802) PR #13442 removed scroll-based highlight clearing. This commit adds Playwright tests verifying: scroll events never clear marks, query-change clearing still works, and no marks appear without ?q= parameter. Restores test fixture files dropped during rebase (source files were in the skipped JS fix commit). Updates changelog to credit @jtbayly and reference both #9802 and #14047. * Simplify scroll persistence test to use actual scrolling The previous test dispatched quarto-hrChanged/quarto-sectionChanged custom events, which were leftovers from when search code listened to those events. Since #13442 removed those listeners entirely, dispatching those events tested nothing. Replace with actual scroll behavior which is the real user scenario from #14047. * Use role-based locators instead of Algolia CSS classes Replace .aa-DetachedSearchButton and .aa-Input with ARIA role locators (getByRole('button'), getByRole('searchbox')). These are resilient to Algolia autocomplete class name changes and follow Playwright best practices used elsewhere in the test suite. --------- Co-authored-by: Claude Opus 4.6 <[email protected]>
1 parent f6ecb11 commit a3189c4

6 files changed

Lines changed: 68 additions & 1 deletion

File tree

news/changelog-1.9.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ All changes included in 1.9:
120120
- ([#13932](https://github.com/quarto-dev/quarto-cli/pull/13932)): Add `llms-txt: true` option to generate LLM-friendly content for websites. Creates `.llms.md` markdown files alongside HTML pages and a root `llms.txt` index file following the [llms.txt](https://llmstxt.org/) specification.
121121
- ([#13951](https://github.com/quarto-dev/quarto-cli/issues/13951)): Fix `image-lazy-loading` not applying `loading="lazy"` attribute to auto-detected listing images.
122122
- ([#14003](https://github.com/quarto-dev/quarto-cli/pull/14003)): Add text fragments to search result links so browsers scroll to and highlight the matched text on the target page.
123+
- ([#9802](https://github.com/quarto-dev/quarto-cli/issues/9802), [#14047](https://github.com/quarto-dev/quarto-cli/issues/14047)): Fix search term highlighting disappearing on page scroll or layout events when navigating from search results. (author: @jtbayly, [#13442](https://github.com/quarto-dev/quarto-cli/pull/13442))
123124

124125
### `book`
125126

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
*_files/
2-
*.html
2+
*.html
3+
/.quarto/
4+
**/*.quarto_ipynb
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/.quarto/
2+
/_site/
3+
**/*.quarto_ipynb
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
project:
2+
type: website
3+
4+
website:
5+
title: "Search Highlight Test"
6+
navbar:
7+
left:
8+
- href: index.qmd
9+
text: Home
10+
11+
format: html
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: "Search Highlight Test"
3+
---
4+
5+
This page contains a special keyword that we use for testing search highlighting.
6+
7+
The word special appears multiple times on this page to ensure search highlighting works correctly.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { test, expect } from "@playwright/test";
2+
3+
const BASE = './html/search-highlight/_site/index.html';
4+
5+
test('Search highlights persist after scrolling', async ({ page }) => {
6+
await page.goto(`${BASE}?q=special`);
7+
const marks = page.locator('mark');
8+
9+
await expect(marks.first()).toBeVisible({ timeout: 5000 });
10+
const initialCount = await marks.count();
11+
expect(initialCount).toBeGreaterThanOrEqual(2);
12+
13+
// Scroll the page — marks should not be cleared
14+
await page.evaluate(() => window.scrollBy(0, 300));
15+
await page.waitForTimeout(500);
16+
await expect(marks).toHaveCount(initialCount);
17+
});
18+
19+
test('Search highlights cleared when query changes', async ({ page }) => {
20+
await page.goto(`${BASE}?q=special`);
21+
const marks = page.locator('mark');
22+
23+
await expect(marks.first()).toBeVisible({ timeout: 5000 });
24+
25+
// Open the search overlay and type a different query
26+
await page.locator('#quarto-search').getByRole('button').click();
27+
const input = page.getByRole('searchbox');
28+
await expect(input).toBeVisible({ timeout: 2000 });
29+
30+
// Typing a different query triggers onStateChange which clears marks
31+
await input.fill('different');
32+
await expect(page.locator('main mark')).toHaveCount(0, { timeout: 2000 });
33+
});
34+
35+
test('No highlights without search query', async ({ page }) => {
36+
await page.goto(BASE);
37+
38+
// Wait for page to fully load
39+
await expect(page.locator('main')).toBeVisible();
40+
41+
// No marks should exist without ?q= parameter
42+
await expect(page.locator('mark')).toHaveCount(0);
43+
});

0 commit comments

Comments
 (0)