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>
56 lines
2.2 KiB
Go
56 lines
2.2 KiB
Go
package extractor
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
// mockInteractiveBrowser implements InteractiveBrowser for testing without Playwright.
|
|
type mockInteractiveBrowser struct{}
|
|
|
|
func (m mockInteractiveBrowser) Navigate(string) (string, error) { return "", nil }
|
|
func (m mockInteractiveBrowser) GoBack() (string, error) { return "", nil }
|
|
func (m mockInteractiveBrowser) GoForward() (string, error) { return "", nil }
|
|
func (m mockInteractiveBrowser) URL() string { return "" }
|
|
func (m mockInteractiveBrowser) MouseClick(float64, float64, string) error { return nil }
|
|
func (m mockInteractiveBrowser) MouseMove(float64, float64) error { return nil }
|
|
func (m mockInteractiveBrowser) MouseWheel(float64, float64) error { return nil }
|
|
func (m mockInteractiveBrowser) KeyboardType(string) error { return nil }
|
|
func (m mockInteractiveBrowser) KeyboardPress(string) error { return nil }
|
|
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) Close() error { return nil }
|
|
|
|
func TestPromoteToInteractive_NonPromotable(t *testing.T) {
|
|
doc := &mockDocument{}
|
|
_, err := PromoteToInteractive(doc)
|
|
if !errors.Is(err, ErrNotPromotable) {
|
|
t.Fatalf("expected ErrNotPromotable, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPromoteToInteractive_AlreadyDetached(t *testing.T) {
|
|
d := &document{detached: true}
|
|
_, err := PromoteToInteractive(d)
|
|
if !errors.Is(err, ErrAlreadyDetached) {
|
|
t.Fatalf("expected ErrAlreadyDetached, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDemoteToDocument_NonDemotable(t *testing.T) {
|
|
ib := &mockInteractiveBrowser{}
|
|
_, err := DemoteToDocument(ib)
|
|
if !errors.Is(err, ErrNotDemotable) {
|
|
t.Fatalf("expected ErrNotDemotable, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDemoteToDocument_AlreadyDetached(t *testing.T) {
|
|
ib := &interactiveBrowser{detached: true}
|
|
_, err := DemoteToDocument(ib)
|
|
if !errors.Is(err, ErrAlreadyDetached) {
|
|
t.Fatalf("expected ErrAlreadyDetached, got: %v", err)
|
|
}
|
|
}
|