All checks were successful
CI / Build container images (pull_request) Successful in 1m8s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m35s
CI / Build container images (push) Has been skipped
CI / Lint, typecheck, test (pull_request) Successful in 4m25s
CI / Auth e2e pack (pull_request) Successful in 6m49s
CI / Import/export fidelity gate (pull_request) Successful in 54s
Release / Build release images and notes (push) Successful in 1m12s
Prod deploy / Deploy the released images to Prod (push) Successful in 15s
CI / Import/export fidelity gate (push) Successful in 54s
CD / Build and push images (push) Successful in 16s
CD / Deploy to Test (push) Successful in 12s
CD / Smoke tests against Test (push) Successful in 1m15s
Release / Release-candidate operations QA (push) Successful in 45s
CI / Auth e2e pack (push) Successful in 6m40s
Der Spec klickte nach page.reload() den Mode-Toggle „um den Edit-Modus zu verlassen" — nach dem Reload ist die Seite aber schon im Lesemodus (React- State resettet), der Klick wechselte also HINEIN. Das passierte jahrelang folgenlos, weil der Fokus auf dem Toggle-Button blieb und „/" die Suche öffnete. Seit dem Editor-Auto-Fokus (PR #140) landet der Fokus im Editor und „/" wird dort zu Text — je nach Ausgang des Rennens gegen den rAF- verzögerten Fokus mal grün (Läufe 381/385), mal rot (383/387/389/390). Fix: den Klick streichen; „/" läuft im Lesemodus als globaler Shortcut. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0155v2aT8AG1kZDQEZiCLBWC
71 lines
3.2 KiB
TypeScript
71 lines
3.2 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
import { contextForUser } from './helpers';
|
|
|
|
/**
|
|
* Search UI pack (issue #50). Adds body content to a page through the editor
|
|
* (indexed by #49 via the collab persistence hook), then opens the search
|
|
* palette with the "/" shortcut and checks that the content is found, the match
|
|
* is highlighted, the scope toggle works, and Enter opens the page.
|
|
* Language-independent selectors (CSS classes + unique content).
|
|
*/
|
|
const BASE_URL = process.env.E2E_BASE_URL ?? 'http://localhost:5173';
|
|
|
|
type Ctx = Awaited<ReturnType<typeof contextForUser>>;
|
|
|
|
async function personalPond(context: Ctx): Promise<{ id: string; slug: string }> {
|
|
const ponds = await context.request.get('/api/v1/ponds');
|
|
const pond = (await ponds.json()).find((p: { type: string }) => p.type === 'personal');
|
|
return { id: pond.id, slug: pond.slug };
|
|
}
|
|
|
|
test('search finds page content, highlights it, and is keyboard-operable', async ({ browser }) => {
|
|
const context = await contextForUser(browser, BASE_URL, 'fixture-user');
|
|
const pond = await personalPond(context);
|
|
const ts = Date.now();
|
|
const word = `srchword${ts}`;
|
|
const title = `Search Page ${ts}`;
|
|
const created = await (
|
|
await context.request.post(`/api/v1/ponds/${pond.id}/pages`, { data: { title } })
|
|
).json();
|
|
|
|
const page = await context.newPage();
|
|
await page.goto(`/p/${pond.slug}/${created.slug}`);
|
|
|
|
// Add body content through the editor, then reload to flush it to the index.
|
|
await page.locator('.editor-page__mode-toggle').click();
|
|
const body = page.locator('.editor-content .ProseMirror');
|
|
await body.click();
|
|
await page.keyboard.type(`the unique ${word} lives in this body`);
|
|
await page.reload();
|
|
await expect(page.locator('.editor-content')).toContainText(word);
|
|
// The reload already landed back in read mode (the mode state resets), so
|
|
// "/" acts as the global shortcut here. This spec used to click the mode
|
|
// toggle again "to leave edit mode" — which actually RE-ENTERED it; that
|
|
// passed only while entering edit mode left focus on the toggle button.
|
|
// Since the editor grabs focus on entering edit mode (PR #140), "/" would
|
|
// become ordinary editor input there, racing the deferred focus — the
|
|
// intermittent-then-persistent failure of this pack.
|
|
|
|
// Open search with the "/" shortcut.
|
|
await page.keyboard.press('/');
|
|
const palette = page.locator('.search-palette');
|
|
await expect(palette).toBeVisible();
|
|
|
|
await palette.locator('.search-palette__input').fill(word);
|
|
const result = page.locator('.search-result', { hasText: title });
|
|
await expect(result).toBeVisible();
|
|
// The matched word is highlighted in the snippet.
|
|
await expect(page.locator('.search-result__snippet mark')).toBeVisible();
|
|
|
|
// Scope toggle is present and keeps the result (page is in the user's ponds).
|
|
await palette.locator('.search-palette__scope input[type="checkbox"]').first().check();
|
|
await expect(page.locator('.search-result', { hasText: title })).toBeVisible();
|
|
|
|
// Enter opens the selected result.
|
|
await palette.locator('.search-palette__input').press('Enter');
|
|
await expect(page).toHaveURL(new RegExp(`/p/${pond.slug}/${created.slug}$`));
|
|
|
|
await context.close();
|
|
});
|