From fb528acf87ecb41424e032731f667c2bf486c832 Mon Sep 17 00:00:00 2001 From: SentienceDEV Date: Tue, 10 Feb 2026 21:58:19 -0800 Subject: [PATCH] fix release pkg --- src/actions.ts | 10 ++++++---- tests/actions-search-timeout.test.ts | 29 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 tests/actions-search-timeout.test.ts diff --git a/src/actions.ts b/src/actions.ts index 27485f7..95ba568 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -1134,12 +1134,14 @@ export async function search( const urlBefore = page.url(); const url = buildSearchUrl(query, engine); await browser.goto(url); - // Some search engines keep long-lived background requests open in CI, - // so treat networkidle as a best-effort signal instead of a hard requirement. + // Use lightweight readiness checks instead of networkidle. + // On Windows CI and some search engines, networkidle can remain pending due to + // long-lived background requests and cause flaky timeouts. try { - await page.waitForLoadState('networkidle', { timeout: 5000 }); + await page.waitForLoadState('domcontentloaded', { timeout: 5000 }); + await page.waitForLoadState('load', { timeout: 5000 }); } catch { - // no-op: page is already loaded enough for URL/result assertions + // best-effort only; URL/outcome assertions do not require full idle } const durationMs = Date.now() - startTime; diff --git a/tests/actions-search-timeout.test.ts b/tests/actions-search-timeout.test.ts new file mode 100644 index 0000000..9ea2bb6 --- /dev/null +++ b/tests/actions-search-timeout.test.ts @@ -0,0 +1,29 @@ +import { search } from '../src/actions'; + +describe('search timeout hardening', () => { + it('returns success when post-goto load-state wait times out', async () => { + const page = { + url: jest + .fn() + .mockReturnValueOnce('https://example.com') + .mockReturnValue('https://duckduckgo.com/?q=sentience+sdk'), + waitForLoadState: jest.fn().mockRejectedValue(new Error('Timeout 30000ms exceeded.')), + }; + + const browser = { + goto: jest.fn().mockResolvedValue(undefined), + snapshot: jest.fn(), + getPage: jest.fn().mockReturnValue(page), + getContext: jest.fn().mockReturnValue(null), + getApiKey: jest.fn().mockReturnValue(undefined), + getApiUrl: jest.fn().mockReturnValue(undefined), + } as any; + + const result = await search(browser, 'sentience sdk', 'duckduckgo'); + + expect(result.success).toBe(true); + expect(result.outcome).toBe('navigated'); + expect(browser.goto).toHaveBeenCalledWith('https://duckduckgo.com/?q=sentience+sdk'); + expect(page.waitForLoadState).toHaveBeenCalled(); + }); +});