|
1 | 1 | import { test, expect } from "@playwright/test"; |
2 | 2 |
|
3 | | -test('Search highlights persist after page load', async ({ page }) => { |
4 | | - await page.goto('./html/search-highlight/_site/index.html?q=special'); |
| 3 | +const BASE = './html/search-highlight/_site/index.html'; |
| 4 | + |
| 5 | +test('Search highlights not cleared by scroll events', async ({ page }) => { |
| 6 | + await page.goto(`${BASE}?q=special`); |
5 | 7 | const marks = page.locator('mark'); |
6 | 8 |
|
7 | | - // Marks should exist after page load |
8 | 9 | await expect(marks.first()).toBeVisible({ timeout: 5000 }); |
| 10 | + const initialCount = await marks.count(); |
| 11 | + expect(initialCount).toBeGreaterThanOrEqual(2); |
9 | 12 |
|
10 | | - // Simulate the layout-triggered quarto-hrChanged event that clears marks |
11 | | - // prematurely without the fix (#14047). With the fix, the listener is |
12 | | - // registered after a delay, so early events like this are ignored. |
| 13 | + // Dispatch layout events immediately (previously cleared marks via quarto-hrChanged) |
13 | 14 | await page.evaluate(() => { |
14 | 15 | window.dispatchEvent(new CustomEvent('quarto-hrChanged')); |
| 16 | + window.dispatchEvent(new CustomEvent('quarto-sectionChanged')); |
15 | 17 | }); |
| 18 | + await expect(marks).toHaveCount(initialCount); |
16 | 19 |
|
17 | | - // Marks should still be visible after the simulated layout event |
18 | | - await expect(marks.first()).toBeVisible(); |
19 | | - await expect(marks.first()).toContainText(/special/i); |
| 20 | + // Wait and dispatch again — marks should persist at any time |
| 21 | + await page.waitForTimeout(1500); |
| 22 | + await page.evaluate(() => { |
| 23 | + window.dispatchEvent(new CustomEvent('quarto-hrChanged')); |
| 24 | + window.dispatchEvent(new CustomEvent('quarto-sectionChanged')); |
| 25 | + }); |
| 26 | + await expect(marks).toHaveCount(initialCount); |
20 | 27 | }); |
21 | 28 |
|
22 | | -test('Search highlights are cleared by scroll after delay', async ({ page }) => { |
23 | | - await page.goto('./html/search-highlight/_site/index.html?q=special'); |
| 29 | +test('Search highlights cleared when query changes', async ({ page }) => { |
| 30 | + await page.goto(`${BASE}?q=special`); |
24 | 31 | const marks = page.locator('mark'); |
25 | 32 |
|
26 | | - // Marks should exist after page load |
27 | 33 | await expect(marks.first()).toBeVisible({ timeout: 5000 }); |
28 | 34 |
|
29 | | - // Wait for the delayed listener registration (1000ms in quarto-search.js) |
30 | | - await page.waitForTimeout(1500); |
| 35 | + // Open the detached search overlay |
| 36 | + await page.locator('.aa-DetachedSearchButton').click(); |
| 37 | + const input = page.locator('.aa-Input'); |
| 38 | + await expect(input).toBeVisible({ timeout: 2000 }); |
31 | 39 |
|
32 | | - // Now quarto-hrChanged should clear marks (listener is registered) |
33 | | - await page.evaluate(() => { |
34 | | - window.dispatchEvent(new CustomEvent('quarto-hrChanged')); |
35 | | - }); |
| 40 | + // Type a different query — triggers onStateChange which clears marks |
| 41 | + await input.fill('different'); |
| 42 | + await expect(page.locator('main mark')).toHaveCount(0, { timeout: 2000 }); |
| 43 | +}); |
| 44 | + |
| 45 | +test('No highlights without search query', async ({ page }) => { |
| 46 | + await page.goto(BASE); |
| 47 | + |
| 48 | + // Wait for page to fully load |
| 49 | + await expect(page.locator('main')).toBeVisible(); |
36 | 50 |
|
37 | | - await expect(marks).toHaveCount(0); |
| 51 | + // No marks should exist without ?q= parameter |
| 52 | + await expect(page.locator('mark')).toHaveCount(0); |
38 | 53 | }); |
0 commit comments