diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ddfea55..df12563 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -50,13 +50,13 @@ jobs: run: npm test - name: Install Playwright browsers - run: npx playwright install --with-deps chromium + run: npx playwright install --with-deps chromium webkit - name: Build the Cloudflare site for E2E tests run: npm run build:cloudflare - - name: Run E2E tests on desktop - run: npx playwright test --project=desktop-chrome + - name: Run E2E tests on desktop and iPhone + run: npx playwright test --project=desktop-chrome --project=iphone build: name: Build Static Site diff --git a/website/app/components/SearchBar.tsx b/website/app/components/SearchBar.tsx index aad6b9a..13f02c4 100644 --- a/website/app/components/SearchBar.tsx +++ b/website/app/components/SearchBar.tsx @@ -22,6 +22,7 @@ const resultOptionId = (resultsListId: string, index: number) => `${resultsListI export default function SearchBar({ patterns, onSelect }: SearchBarProps) { const [searchQuery, setSearchQuery] = useState('') + const [isHydrated, setIsHydrated] = useState(false) const [isOpen, setIsOpen] = useState(false) const [selectedIndex, setSelectedIndex] = useState(-1) const [filteredPatterns, setFilteredPatterns] = useState({ @@ -37,6 +38,11 @@ export default function SearchBar({ patterns, onSelect }: SearchBarProps) { const categoryOrder: PatternCategory[] = ['obstacles', 'anti-patterns', 'patterns'] + useEffect(() => { + setSearchQuery(inputRef.current?.value ?? '') + setIsHydrated(true) + }, []) + useEffect(() => { if (searchQuery.trim() === '') { setFilteredPatterns({ @@ -173,7 +179,7 @@ export default function SearchBar({ patterns, onSelect }: SearchBarProps) { aria-activedescendant={activeOptionId} className={styles.searchInput} placeholder="Search patterns..." - value={searchQuery} + value={isHydrated ? searchQuery : undefined} onChange={e => setSearchQuery(e.target.value)} onKeyDown={handleKeyDown} onBlur={() => setIsOpen(false)} diff --git a/website/tests/e2e/smoke.spec.ts b/website/tests/e2e/smoke.spec.ts index c20d273..042ee81 100644 --- a/website/tests/e2e/smoke.spec.ts +++ b/website/tests/e2e/smoke.spec.ts @@ -117,6 +117,20 @@ test.describe('Search Functionality', () => { await expect(searchResults(page).getByRole('option').first()).toBeVisible(); }); + test('text typed while the page is still loading is kept', async ({ page }) => { + await page.route('**/_next/static/chunks/**', async route => { + await new Promise(resolve => setTimeout(resolve, 2000)); + await route.continue(); + }); + await page.goto('/', { waitUntil: 'commit' }); + + await searchBox(page).focus(); + await page.keyboard.type('active'); + + await expect(searchResults(page).getByRole('option', { name: 'Active Partner' })).toBeVisible(); + await expect(searchBox(page)).toHaveValue('active'); + }); + test('clicking a search result navigates to correct pattern page', async ({ page }) => { await page.goto('/');