Add PromoteToInteractive(Document) (InteractiveBrowser, error) to transfer a live page from scraping mode to interactive mode (e.g. for human captcha solving)
Add DemoteToDocument(InteractiveBrowser) (Document, error) to transfer back to scraping mode on the same page
Both functions use a detached flag so the original handle's Close() becomes a no-op (page ownership transfers cleanly)
Promoted InteractiveBrowser does not own the Playwright infrastructure — only the page — so the original Browser must stay alive
Design
Package-level functions (not interface methods) to avoid breaking changes. Uses type assertion on the concrete *document / *interactiveBrowser types — same pattern as pageEvaluator in readability.go.
## Summary
- Add `PromoteToInteractive(Document) (InteractiveBrowser, error)` to transfer a live page from scraping mode to interactive mode (e.g. for human captcha solving)
- Add `DemoteToDocument(InteractiveBrowser) (Document, error)` to transfer back to scraping mode on the same page
- Both functions use a `detached` flag so the original handle's `Close()` becomes a no-op (page ownership transfers cleanly)
- Promoted `InteractiveBrowser` does not own the Playwright infrastructure — only the page — so the original `Browser` must stay alive
## Design
Package-level functions (not interface methods) to avoid breaking changes. Uses type assertion on the concrete `*document` / `*interactiveBrowser` types — same pattern as `pageEvaluator` in `readability.go`.
## Test plan
- [x] `TestPromoteToInteractive_NonPromotable` — mock document returns `ErrNotPromotable`
- [x] `TestPromoteToInteractive_AlreadyDetached` — double-promote returns `ErrAlreadyDetached`
- [x] `TestDemoteToDocument_NonDemotable` — mock interactive browser returns `ErrNotDemotable`
- [x] `TestDemoteToDocument_AlreadyDetached` — double-demote returns `ErrAlreadyDetached`
- [x] `go build ./...`, `go test ./...`, `go vet ./...` all pass
Closes #76
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 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
PromoteToInteractive(Document) (InteractiveBrowser, error)to transfer a live page from scraping mode to interactive mode (e.g. for human captcha solving)DemoteToDocument(InteractiveBrowser) (Document, error)to transfer back to scraping mode on the same pagedetachedflag so the original handle'sClose()becomes a no-op (page ownership transfers cleanly)InteractiveBrowserdoes not own the Playwright infrastructure — only the page — so the originalBrowsermust stay aliveDesign
Package-level functions (not interface methods) to avoid breaking changes. Uses type assertion on the concrete
*document/*interactiveBrowsertypes — same pattern aspageEvaluatorinreadability.go.Test plan
TestPromoteToInteractive_NonPromotable— mock document returnsErrNotPromotableTestPromoteToInteractive_AlreadyDetached— double-promote returnsErrAlreadyDetachedTestDemoteToDocument_NonDemotable— mock interactive browser returnsErrNotDemotableTestDemoteToDocument_AlreadyDetached— double-demote returnsErrAlreadyDetachedgo build ./...,go test ./...,go vet ./...all passCloses #76