diff --git a/common/frame.go b/common/frame.go index 8245ca54e..51e44855f 100644 --- a/common/frame.go +++ b/common/frame.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "sync" "time" @@ -563,15 +564,35 @@ func (f *Frame) waitForSelector(selector string, opts *FrameWaitForSelectorOptio return handle, nil } -func (f *Frame) waitFor(selector string, opts *FrameWaitForSelectorOptions) error { +func (f *Frame) waitFor(selector string, opts *FrameWaitForSelectorOptions, retryCount int) error { f.log.Debugf("Frame:waitFor", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector) + retryCount-- + if retryCount < 0 { + return errors.New("waitFor retry threshold reached") + } + document, err := f.document() if err != nil { + if strings.Contains(err.Error(), "Cannot find context with specified id") { + return f.waitFor(selector, opts, retryCount) + } return err } _, err = document.waitForSelector(f.ctx, selector, opts) + if err != nil { + if strings.Contains(err.Error(), "Inspected target navigated or closed") { + return f.waitFor(selector, opts, retryCount) + } + if strings.Contains(err.Error(), "Cannot find context with specified id") { + return f.waitFor(selector, opts, retryCount) + } + if strings.Contains(err.Error(), "Execution context was destroyed") { + return f.waitFor(selector, opts, retryCount) + } + } + return err } diff --git a/common/locator.go b/common/locator.go index 3b49f3b5c..0bc69cc3b 100644 --- a/common/locator.go +++ b/common/locator.go @@ -621,7 +621,7 @@ func (l *Locator) WaitFor(opts sobek.Value) error { func (l *Locator) waitFor(opts *FrameWaitForSelectorOptions) error { opts.Strict = true - return l.frame.waitFor(l.selector, opts) + return l.frame.waitFor(l.selector, opts, 20) } // DefaultTimeout returns the default timeout for the locator.