feat: add PromoteToInteractive and DemoteToDocument for mid-session page transfer
Allow transferring ownership of a Playwright page between Document and InteractiveBrowser modes without tearing down the browser. This enables handing a live page to a human (e.g. for captcha solving) and resuming scraping on the same page afterward. Closes #76 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -48,10 +48,12 @@ type InteractiveBrowser interface {
|
||||
}
|
||||
|
||||
type interactiveBrowser struct {
|
||||
pw *playwright.Playwright
|
||||
browser playwright.Browser
|
||||
ctx playwright.BrowserContext
|
||||
page playwright.Page
|
||||
pw *playwright.Playwright
|
||||
browser playwright.Browser
|
||||
ctx playwright.BrowserContext
|
||||
page playwright.Page
|
||||
ownsInfrastructure bool
|
||||
detached bool
|
||||
}
|
||||
|
||||
// NewInteractiveBrowser creates a headless browser with a page ready for interactive control.
|
||||
@@ -94,10 +96,11 @@ func NewInteractiveBrowser(ctx context.Context, opts ...BrowserOptions) (Interac
|
||||
|
||||
ch <- result{
|
||||
ib: &interactiveBrowser{
|
||||
pw: res.pw,
|
||||
browser: res.browser,
|
||||
ctx: res.bctx,
|
||||
page: page,
|
||||
pw: res.pw,
|
||||
browser: res.browser,
|
||||
ctx: res.bctx,
|
||||
page: page,
|
||||
ownsInfrastructure: true,
|
||||
},
|
||||
}
|
||||
}()
|
||||
@@ -194,25 +197,31 @@ func (ib *interactiveBrowser) Cookies() ([]Cookie, error) {
|
||||
}
|
||||
|
||||
func (ib *interactiveBrowser) Close() error {
|
||||
if ib.detached {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errs []error
|
||||
if ib.page != nil {
|
||||
if err := ib.page.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if ib.ctx != nil {
|
||||
if err := ib.ctx.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
if ib.ownsInfrastructure {
|
||||
if ib.ctx != nil {
|
||||
if err := ib.ctx.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ib.browser != nil {
|
||||
if err := ib.browser.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
if ib.browser != nil {
|
||||
if err := ib.browser.Close(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ib.pw != nil {
|
||||
if err := ib.pw.Stop(); err != nil {
|
||||
errs = append(errs, err)
|
||||
if ib.pw != nil {
|
||||
if err := ib.pw.Stop(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user