From adefaaef36c6177969c27aa77fde655d7f5be39b Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Tue, 17 Mar 2026 01:59:16 +0000 Subject: [PATCH] feat: add SetDefaultTimeout to InteractiveBrowser interface Adds SetDefaultTimeout(time.Duration) to the InteractiveBrowser interface, delegating to Playwright's Page and BrowserContext SetDefaultTimeout and SetDefaultNavigationTimeout methods. This allows callers to set a timeout so Playwright operations return an error instead of blocking forever when the browser process crashes or the remote server becomes unresponsive. Closes #86 Co-Authored-By: Claude Opus 4.6 --- interactive.go | 18 ++++++++++++++++++ promote_test.go | 2 ++ 2 files changed, 20 insertions(+) diff --git a/interactive.go b/interactive.go index db63b3f..075c037 100644 --- a/interactive.go +++ b/interactive.go @@ -48,6 +48,16 @@ type InteractiveBrowser interface { // Cookies returns all cookies from the browser context. Cookies() ([]Cookie, error) + // SetDefaultTimeout sets the default timeout for all Playwright operations + // (navigation, clicks, screenshots, cookie extraction, etc.). A value of 0 + // disables timeouts. By default, Playwright uses a 30-second timeout. + // + // This is the primary mechanism for preventing hung sessions: callers can + // set a timeout so that any Playwright call returns an error instead of + // blocking forever if the browser process crashes or the remote server + // becomes unresponsive. + SetDefaultTimeout(timeout time.Duration) + // Close tears down the browser. Close() error } @@ -246,6 +256,14 @@ func (ib *interactiveBrowser) Cookies() ([]Cookie, error) { return cookies, nil } +func (ib *interactiveBrowser) SetDefaultTimeout(timeout time.Duration) { + ms := float64(timeout.Milliseconds()) + ib.page.SetDefaultTimeout(ms) + ib.page.SetDefaultNavigationTimeout(ms) + ib.ctx.SetDefaultTimeout(ms) + ib.ctx.SetDefaultNavigationTimeout(ms) +} + func (ib *interactiveBrowser) Close() error { if ib.detached { return nil diff --git a/promote_test.go b/promote_test.go index c5ba28c..d1ca4e3 100644 --- a/promote_test.go +++ b/promote_test.go @@ -3,6 +3,7 @@ package extractor import ( "errors" "testing" + "time" ) // mockInteractiveBrowser implements InteractiveBrowser for testing without Playwright. @@ -22,6 +23,7 @@ func (m mockInteractiveBrowser) KeyboardPress(string) error { return func (m mockInteractiveBrowser) KeyboardInsertText(string) error { return nil } func (m mockInteractiveBrowser) Screenshot(int) ([]byte, error) { return nil, nil } func (m mockInteractiveBrowser) Cookies() ([]Cookie, error) { return nil, nil } +func (m mockInteractiveBrowser) SetDefaultTimeout(time.Duration) {} func (m mockInteractiveBrowser) Close() error { return nil } func TestPromoteToInteractive_NonPromotable(t *testing.T) {