diff --git a/baidu/search.go b/baidu/search.go index 503e19e..cbd6343 100644 --- a/baidu/search.go +++ b/baidu/search.go @@ -160,7 +160,12 @@ func (baid *Baidu) waitForParsedSearchResults(ctx context.Context, page *rod.Pag } return nil, core.ErrParser } - return nil, nil + // The page never reached a recognizable state: no result containers, no + // captcha or timeout markers. Baidu hydrates result cards client-side and + // can exceed the selector deadline, so report a timeout rather than a + // successful empty SERP — callers must retry/skip, not trust 0 results. + baid.logger.Debug("No result containers or block markers within selector timeout") + return nil, core.ErrSearchTimeout } // SearchImage executes a Baidu image search and returns normalized image diff --git a/baidu/search_integration_test.go b/baidu/search_integration_test.go index 2d32919..0257e5a 100644 --- a/baidu/search_integration_test.go +++ b/baidu/search_integration_test.go @@ -12,6 +12,6 @@ import ( func TestSearchBaidu(t *testing.T) { ithelper.RunEngineTests(t, func(b *core.Browser) core.SearchEngine { - return New(*b, core.SearchEngineOptions{}) + return New(*b, ithelper.EngineOptions()) }) } diff --git a/bing/search_integration_test.go b/bing/search_integration_test.go index 2ddb6d2..179f255 100644 --- a/bing/search_integration_test.go +++ b/bing/search_integration_test.go @@ -12,6 +12,6 @@ import ( func TestSearchBing(t *testing.T) { ithelper.RunEngineTests(t, func(b *core.Browser) core.SearchEngine { - return New(*b, core.SearchEngineOptions{}) + return New(*b, ithelper.EngineOptions()) }) } diff --git a/duckduckgo/search_integration_test.go b/duckduckgo/search_integration_test.go index 2f01f8b..3b52c3d 100644 --- a/duckduckgo/search_integration_test.go +++ b/duckduckgo/search_integration_test.go @@ -12,6 +12,6 @@ import ( func TestSearchDuckDuckGo(t *testing.T) { ithelper.RunEngineTests(t, func(b *core.Browser) core.SearchEngine { - return New(*b, core.SearchEngineOptions{}) + return New(*b, ithelper.EngineOptions()) }) } diff --git a/ecosia/search_integration_test.go b/ecosia/search_integration_test.go index 1047309..c6249fa 100644 --- a/ecosia/search_integration_test.go +++ b/ecosia/search_integration_test.go @@ -12,6 +12,6 @@ import ( func TestSearchEcosia(t *testing.T) { ithelper.RunEngineTests(t, func(b *core.Browser) core.SearchEngine { - return New(*b, core.SearchEngineOptions{}) + return New(*b, ithelper.EngineOptions()) }) } diff --git a/google/search_integration_test.go b/google/search_integration_test.go index 3dcf9b8..c65bc79 100644 --- a/google/search_integration_test.go +++ b/google/search_integration_test.go @@ -12,6 +12,6 @@ import ( func TestSearchGoogle(t *testing.T) { ithelper.RunEngineTests(t, func(b *core.Browser) core.SearchEngine { - return New(*b, core.SearchEngineOptions{}) + return New(*b, ithelper.EngineOptions()) }) } diff --git a/testutil/ithelper/ithelper.go b/testutil/ithelper/ithelper.go index 5c43e28..350fe82 100644 --- a/testutil/ithelper/ithelper.go +++ b/testutil/ithelper/ithelper.go @@ -47,6 +47,13 @@ func HandleError(t *testing.T, operation string, err error) { t.Skipf("skipping flaky live %s: %v", operation, err) } +// EngineOptions returns engine options tuned for live-site integration runs. +// Real SERPs (Baidu especially) hydrate result cards client-side and can take +// well past the 5s default selector timeout on a first visit. +func EngineOptions() core.SearchEngineOptions { + return core.SearchEngineOptions{SelectorTimeout: 15} +} + // CreateBrowser creates a browser configured for integration tests and closes // it when the test finishes. Respects OPENSERP_INTEGRATION_HEADFUL for // debugging (browser and page are left open for inspection). diff --git a/yandex/search_integration_test.go b/yandex/search_integration_test.go index 2fffa93..2a7c44f 100644 --- a/yandex/search_integration_test.go +++ b/yandex/search_integration_test.go @@ -12,6 +12,6 @@ import ( func TestSearchYandex(t *testing.T) { ithelper.RunEngineTests(t, func(b *core.Browser) core.SearchEngine { - return New(*b, core.SearchEngineOptions{}) + return New(*b, ithelper.EngineOptions()) }) }