feat(indstillinger): en indstilling kan findes ved at søge efter den
Indstillingerne er ti faner med syvogtredive afsnit, og den eneste vej til et bestemt af dem var at huske, hvilken fane det lå under. ⌘K kunne opgaver, projekter og noter — alt det, man selv har skrevet, og intet af det, programmet består af. Ét indeks, to steder det bruges: et felt øverst i indstillingerne og paletten. To lister over de samme afsnit ville være to steder at glemme et nyt et. Overskrifterne står ikke i indekset. Hver post peger på den nøgle, afsnittets egen overskrift allerede bruger, så et afsnit, der bliver omdøbt, følger med af sig selv, og søgningen kan begge sprog uden at kende nogen af dem. `words` er derimod skrevet i indekset, og det er med vilje: det er søgeord, ingen får at se. Det danske afsnit hedder "Tælling af installationer", men det ord, man kender det ved, er "beacon" — og på samme måde 2fa, imap, webcal, webhook. De er de samme på begge sprog, hvilket er hele grunden til, at de virker som søgeord. Ankrene er nye id'er på afsnittene. Tre af dem stødte sammen med et felt inde i afsnittet — to ens id'er gør <label for> tvetydig og getElementById tilfældig — og hedder derfor to-faktor, kalenderfeed og caldav-server. Springet dertil kan ikke overlades til browseren: siden hentes af ruteren, og afsnittet findes først, når dens data er hjemme. Der prøves i to sekunder og gives så op. Blinket bagefter er ikke pynt — man er landet midt i en side med otte afsnit, man ikke selv rullede hen til. Prøverne læser filerne frem for at klikke: halvdelen af afsnittene vises kun under en betingelse, så en prøve, der ledte efter dem i en browser, ville melde fejl på det, der med rette var skjult. Og palettens pladsholder sagde "Søg i opgaver og projekter". Den har kunnet noter længe, og kan nu også indstillinger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1f0a43ac90
commit
7e981354c2
@@ -4454,3 +4454,64 @@ test('adresserne på integrationssiden kan ses helt på en telefon', async ({ pa
|
||||
|
||||
expect(trouble).toEqual([]);
|
||||
});
|
||||
|
||||
/**
|
||||
* En indstilling kan findes ved at søge efter den.
|
||||
*
|
||||
* Indstillingerne er ti faner med en snes afsnit, og den eneste vej til et
|
||||
* bestemt af dem var at huske, hvilken fane det lå under. Prøven går begge veje
|
||||
* ind: feltet øverst i indstillingerne, og ⌘K, som ikke kunne andet end det, man
|
||||
* selv har skrevet.
|
||||
*
|
||||
* "beacon" er valgt med vilje. Afsnittet hedder "Tælling af installationer" på
|
||||
* dansk, så en søgning, der kun læste overskrifterne, ville ikke finde det — og
|
||||
* "beacon" er præcis det ord, man kender det ved. Det er derfor indekset har et
|
||||
* felt med søgeord, ingen får at se.
|
||||
*/
|
||||
test('en indstilling kan findes ved at søge efter den', async ({ page }) => {
|
||||
const trouble = watchForTrouble(page);
|
||||
await page.goto('/indstillinger');
|
||||
|
||||
const find = page.getByPlaceholder('Søg i indstillinger');
|
||||
await find.fill('beacon');
|
||||
|
||||
const hit = page.locator('.hits button', { hasText: 'Tælling af installationer' });
|
||||
await expect(hit).toBeVisible();
|
||||
// Hvor det ligger, står ved siden af hvad det hedder: halvdelen af det, man
|
||||
// søgte efter, er svaret på hvilken fane.
|
||||
await expect(hit).toContainText('Data');
|
||||
await hit.click();
|
||||
|
||||
await expect(page).toHaveURL(/\/indstillinger\/data#beacon$/);
|
||||
const section = page.locator('#beacon');
|
||||
await expect(section.getByRole('heading', { name: 'Tælling af installationer' })).toBeVisible();
|
||||
// Rullet derhen, ikke bare tegnet: afsnittet er det syvende på siden, så en
|
||||
// side, der bare blev åbnet, ville vise toppen af den.
|
||||
await expect(section).toBeInViewport();
|
||||
|
||||
// Feltet tømmer sig selv, når man er landet. En søgning, der bliver stående
|
||||
// over det, man fandt, dækker det.
|
||||
await expect(find).toHaveValue('');
|
||||
|
||||
// Og det, der ikke findes, siger det frem for at vise en tom liste.
|
||||
await find.fill('hestevogn');
|
||||
await expect(page.getByText('Ingen indstilling hedder det.')).toBeVisible();
|
||||
|
||||
// ⌘K spørger det samme indeks. Her er det den anden vej ind, og "webhook" er
|
||||
// igen et ord, der ikke står i overskriften.
|
||||
await page.goto('/');
|
||||
// Knappen og ikke tastetrykket: ⌘K lyttes der efter i en effekt, så et tryk
|
||||
// sendt lige efter goto kan nå frem, før siden er hydreret. Knappen venter
|
||||
// Playwright på af sig selv — og den er også den, man har på en telefon.
|
||||
await page.getByRole('button', { name: /Søg/ }).click();
|
||||
await page.getByRole('dialog').getByRole('textbox').fill('webhook');
|
||||
const row = page.getByRole('dialog').locator('li button', { hasText: 'Skub fra andre programmer' });
|
||||
await expect(row).toBeVisible();
|
||||
await expect(row).toContainText('Indstilling');
|
||||
await row.click();
|
||||
|
||||
await expect(page).toHaveURL(/\/indstillinger\/integrationer#krog$/);
|
||||
await expect(page.locator('#krog')).toBeInViewport();
|
||||
|
||||
expect(trouble).toEqual([]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user