diff --git a/app/components/SearchBox.vue b/app/components/SearchBox.vue index ce354da2..e5ae0df6 100644 --- a/app/components/SearchBox.vue +++ b/app/components/SearchBox.vue @@ -15,12 +15,22 @@ const emit = defineEmits(['blur', 'focus']) const router = useRouter() const route = useRoute() +const searchInputRef = useTemplateRef('searchInputRef') const isSearchFocused = ref(false) const showSearchBar = computed(() => { return route.name !== 'index' }) +// Focus input when search bar becomes visible (e.g., when navigating from homepage) +watch(showSearchBar, visible => { + if (visible) { + nextTick(() => { + searchInputRef.value?.focus() + }) + } +}) + // Local input value (updates immediately as user types) const searchQuery = ref((route.query.q as string) ?? '') @@ -84,7 +94,7 @@ function handleSearchFocus() { { await expect(page.locator('input[type="search"]')).toBeFocused() }) + test('/ (homepage) → search, keeps focus on search input', async ({ page, goto }) => { + await goto('/', { waitUntil: 'domcontentloaded' }) + + const homeSearchInput = page.locator('#home-search') + await homeSearchInput.click() + await page.keyboard.type('vue') + + // Wait for navigation to /search (debounce is 250ms) + await expect(page).toHaveURL(/\/search/, { timeout: 10000 }) + await expect(page.locator('text=/found \\d+/i')).toBeVisible({ timeout: 15000 }) + + // Home search input should be gone (we're on /search now) + await expect(homeSearchInput).not.toBeVisible() + + // Header search input should now exist and be focused + const headerSearchInput = page.locator('#header-search') + await expect(headerSearchInput).toBeVisible() + await expect(headerSearchInput).toBeFocused() + }) + test('/settings → search, keeps focus on search input', async ({ page, goto }) => { await goto('/settings', { waitUntil: 'domcontentloaded' }) @@ -43,7 +63,7 @@ test.describe('Search Pages', () => { await page.waitForLoadState('domcontentloaded') - await expect(page.locator('text=/found \\d+/i')).toBeVisible() + await expect(page.locator('text=/found \\d+/i')).toBeVisible({ timeout: 15000 }) await expect(searchInput).toBeFocused() })