Skip to content

Commit d76835b

Browse files
authored
Merge pull request #2031 from dscho/accommodate-for-fast-typers
search: accommodate for fast typers
2 parents e53b394 + 1b19d02 commit d76835b

File tree

4 files changed

+101
-8
lines changed

4 files changed

+101
-8
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@
1313
/node_modules/
1414
/test-results/
1515
/playwright-report/
16+
/tests/git-scm.spec.js-snapshots/*-darwin.png
17+
/tests/git-scm.spec.js-snapshots/*-win32.png

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ $ git sparse-checkout set layouts content static assets hugo.yml data script
2626
$ git reset --hard
2727
```
2828

29+
> [!NOTE]
30+
> On Windows, if you cannot use [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/) for some reason, you will be unable to build the site as-is. The reason is that some URLs of the git-scm.com site contain question marks, for historical reasons. These question marks are obviously encoded as `%3F` in the URLs, but the way Hugo works, they are literal question marks in the filenames of the corresponding files. Such filenames are accommodated easily by Linux filesystems, but on Windows, filenames containing question marks are forbidden. For that reason, to build the site on Windows, the following command needs to be run (assuming a Bash, as the rest of this document):
31+
>
32+
> ```sh
33+
> for file in $(find -name \*.html -exec grep -l '^url: .*?' {} \;)
34+
> do
35+
> git update-index --assume-unchanged "$file" &&
36+
> sed -i '/^url: /s/?//g' "$file" ||
37+
> break
38+
> done
39+
> ```
40+
>
41+
> This edits the affected files' `url` front-matter attributes to avoid writing those files containing question marks. Obviously, the result does not support the backwards-compatible URLs that contain URL-encoded question marks.
42+
2943
> [!NOTE]
3044
> If you _already_ have a full clone and wish to accelerate development by focusing only on a small subset of the pages, you may want to run the `git sparse-checkout set [...]` command mentioned above.
3145
@@ -93,12 +107,66 @@ $ HUGO_UGLYURLS=false hugo
93107
$ npx -y pagefind --site public --serve
94108
```
95109
110+
If you want to make sure that the same Pagefind version is used as when the site is deployed, use this command:
111+
112+
```console
113+
$ npx -y pagefind@$(sed -n 's/^ *pagefind_version: //p' <./hugo.yml) --site public
114+
```
115+
96116
Note that running Pagefind will make the process about 7 times slower, and the site will not be re-rendered and live-reloaded in the browser when you change files in `content/` (unlike with `hugo serve -w`).
97117
98118
## Running the test suite
99119
100120
Believe it or not, https://git-scm.com/ has its own test suite. It uses [Playwright](https://playwright.dev/) to perform a couple of tests that verify that the site "looks right". These tests live in `tests/` and are configured via `playwright.config.js`.
101121
122+
> [!NOTE]
123+
> Building the site, letting Pagefind generate the search index, and then running the test suite can be quite time consuming. To accelerate the development cycle, it is _highly_ recommended to use a sparse checkout instead of a full clone. The minimal sparse checkout required to run the test suite can be configured like this:
124+
>
125+
> ```console
126+
> $ MSYS_NO_PATHCONV=1 git config set --worktree core.sparseCheckoutCone false
127+
> $ git config set --worktree core.sparseCheckout true
128+
> $ git sparse-checkout set \
129+
> /README.md \
130+
> /assets/ \
131+
> /content/404.html \
132+
> /content/_index.html \
133+
> /content/about/small-and-fast.html \
134+
> /content/downloads/guis/ \
135+
> /content/search/ \
136+
> /data/ \
137+
> /external/book/content/book/_index.html \
138+
> /external/book/content/book/az/v2/Başlanğıc-Git-Nədir.html \
139+
> /external/book/content/book/en/v2/Getting-Started-About-Version-Control.html \
140+
> /external/book/content/book/en/v2/_index.html \
141+
> /external/book/content/book/fr/v2/Démarrage-rapide-À-propos-de-la-gestion-de-version.html \
142+
> /external/book/data/ \
143+
> /external/docs/content/docs/git-add/fr.html \
144+
> /external/docs/content/docs/git-clone.html \
145+
> /external/docs/content/docs/git-commit.html \
146+
> /external/docs/content/docs/git-commit/fr.html \
147+
> /external/docs/content/docs/git-config.html \
148+
> /external/docs/content/docs/git-config/fr.html \
149+
> /external/docs/content/docs/git-remote/fr.html \
150+
> /external/docs/content/docs/gitrevisions.html \
151+
> /external/docs/content/docs/gitrevisions/fr.html \
152+
> /external/docs/data/ \
153+
> /hugo.yml \
154+
> /layouts/ \
155+
> /playwright.config.js \
156+
> /script/ \
157+
> /static/ \
158+
> /tests/git-scm.spec.js
159+
> ```
160+
>
161+
> On Windows, unless you're doing all this in WSL, do not forget to run the commands mentioned earlier to edit the `url` front-matter attributes that contain question marks!
162+
>
163+
> The site can then be built quickly via these commands:
164+
>
165+
> ```console
166+
> $ HUGO_MEMORYLIMIT=1 time hugo &&
167+
> npx -y pagefind@$(sed -n 's/^ *pagefind_version: //p' <./hugo.yml) --site public
168+
> ```
169+
102170
To run these tests in your local setup, you need a working node.js installation. After that, you need to install Playwright:
103171
104172
```console
@@ -121,6 +189,9 @@ $ PLAYWRIGHT_TEST_URL='http://localhost:5000/' npx playwright test --project=fir
121189
122190
For more fine-grained testing, you can pass `-g <regex>` to run only the matching test cases.
123191
192+
> [!NOTE]
193+
> When running the test suite on platforms other than Linux, the first run will "fail" in the `dark mode` test case. That is expected! This test case relies on previously-generated screenshots that are stored in `tests/git-scm.spec.js-snapshots/`, and for bandwidth reasons only the Linux ones are committed in the Git repository (because they are required to run the PR/CI builds). The first run will store those screenshots so that subsequent runs of this test case will succeed, though.
194+
124195
## Update manual pages
125196
126197
First, install the Ruby prerequisites:

assets/js/application.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ var Search = {
244244

245245
if(term != Search.currentSearch) {
246246
Search.currentSearch = term;
247+
const language = document.querySelector("html")?.getAttribute("lang");
248+
const allResultsURL = `${baseURLPrefix}search/results?search=${term}${language && `&language=${language}`}`;
247249
$("#search-results").html(`
248250
<header> Search Results </header>
249251
<table>
@@ -253,7 +255,9 @@ var Search = {
253255
<td class="matches">
254256
<ul>
255257
<li>
256-
<a class="highlight" id="show-results-label">Searching for <span id="search-term">&nbsp;</span>...</a>
258+
<a class="highlight" id="show-results-label" href="${allResultsURL}">
259+
Searching for <span id="search-term">&nbsp;</span>...
260+
</a>
257261
</li>
258262
</ul>
259263
</td>
@@ -284,16 +288,12 @@ var Search = {
284288
$("#search-term").text(term);
285289
this.initializeSearchIndex(async () => {
286290
const results = await Search.pagefind.debouncedSearch(term);
287-
if (results === null) return;
288-
if (results.results.length === 0) {
291+
if (results === null || results.results.length === 0) {
289292
$("#show-results-label").text("No matching pages found.");
290293
return;
291294
}
292-
293-
const language = document.querySelector("html")?.getAttribute("lang");
294295
$("#show-results-label")
295296
.text("Show all results...")
296-
.attr('href', `${baseURLPrefix}search/results?search=${term}${language && `&language=${language}`}`);
297297

298298
const loadButton = $("#load-more-results");
299299
loadButton.text(`Loading ${
@@ -371,6 +371,12 @@ var Search = {
371371
selectResultOption: function() {
372372
var link = $('#search-results a')[Search.selectedIndex];
373373
var url = $(link).attr('href');
374+
if (!url) {
375+
const term = $('#search-text').val();
376+
if (!term) return;
377+
const language = document.querySelector("html")?.getAttribute("lang");
378+
url = `${baseURLPrefix}search/results?search=${term}${language && `&language=${language}`}`;
379+
}
374380
window.location.href = url;
375381
selectedIndex = 0;
376382
},

tests/git-scm.spec.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ test.afterEach(async ({ page }, testInfo) => {
2121
}
2222
})
2323

24+
if (process.platform === 'win32') test.setTimeout(60_000) // give it some time
25+
2426
test('generator is Hugo', async ({page}) => {
2527
await page.goto(url)
2628
await expect(page.locator('meta[name="generator"]')).toHaveAttribute('content', /^Hugo /)
@@ -103,9 +105,17 @@ test.describe('Linux', () => {
103105
test('search', async ({ page }) => {
104106
await page.goto(url)
105107

106-
// Search for "commit"
108+
// Full search for "commit"
107109
const searchBox = page.getByPlaceholder('Type / to search entire site…')
108110
await searchBox.fill('commit')
111+
await searchBox.press('Enter')
112+
113+
await expect(page).toHaveURL(/\/search\/results\?search=commit/)
114+
115+
await page.goto(url)
116+
117+
// Search for "commit"
118+
await searchBox.fill('commit')
109119
await searchBox.press('Shift')
110120

111121
// Expect the div to show up
@@ -250,7 +260,11 @@ test('book', async ({ page }) => {
250260

251261
// Navigate to a page whose URL contains a question mark
252262
await page.goto(`${url}book/az/v2/Başlanğıc-Git-Nədir?`)
253-
await expect(page).toHaveURL(/Ba%C5%9Flan%C4%9F%C4%B1c-Git-N%C9%99dir%3F/)
263+
if (process.platform === 'win32' && process.env.PLAYWRIGHT_TEST_URL?.startsWith('http://localhost')) {
264+
await expect(page).toHaveURL(/Ba%C5%9Flan%C4%9F%C4%B1c-Git-N%C9%99dir\?/)
265+
} else {
266+
await expect(page).toHaveURL(/Ba%C5%9Flan%C4%9F%C4%B1c-Git-N%C9%99dir%3F/)
267+
}
254268
await expect(page.getByRole('document')).toHaveText(/Snapshotlar, Fərqlər Yox/)
255269

256270
// the repository URL now points to the Azerbaijani translation

0 commit comments

Comments
 (0)