add TargetID to Target

This will be useful later on, for example to be able to close a target
(a page) once it gets cancelled.
This commit is contained in:
Daniel Martí 2019-04-07 13:36:48 +02:00
parent b647c708b4
commit c313fa1c1d
4 changed files with 31 additions and 37 deletions

View File

@ -34,7 +34,7 @@ type Browser struct {
// tabQueue is the queue used to create new target handlers, once a new // tabQueue is the queue used to create new target handlers, once a new
// tab is created and attached to. The newly created Target is sent back // tab is created and attached to. The newly created Target is sent back
// via tabResult. // via tabResult.
tabQueue chan target.SessionID tabQueue chan newTab
tabResult chan *Target tabResult chan *Target
// cmdQueue is the outgoing command queue. // cmdQueue is the outgoing command queue.
@ -45,6 +45,11 @@ type Browser struct {
errf func(string, ...interface{}) errf func(string, ...interface{})
} }
type newTab struct {
targetID target.ID
sessionID target.SessionID
}
type cmdJob struct { type cmdJob struct {
msg *cdproto.Message msg *cdproto.Message
resp chan *cdproto.Message resp chan *cdproto.Message
@ -60,7 +65,7 @@ func NewBrowser(ctx context.Context, urlstr string, opts ...BrowserOption) (*Bro
b := &Browser{ b := &Browser{
conn: conn, conn: conn,
tabQueue: make(chan target.SessionID, 1), tabQueue: make(chan newTab, 1),
tabResult: make(chan *Target, 1), tabResult: make(chan *Target, 1),
cmdQueue: make(chan cmdJob), cmdQueue: make(chan cmdJob),
@ -105,11 +110,14 @@ func (b *Browser) send(method cdproto.MethodType, params easyjson.RawMessage) er
return b.conn.Write(msg) return b.conn.Write(msg)
} }
func (b *Browser) newExecutorForTarget(ctx context.Context, sessionID target.SessionID) *Target { func (b *Browser) newExecutorForTarget(ctx context.Context, targetID target.ID, sessionID target.SessionID) *Target {
if targetID == "" {
panic("empty target ID")
}
if sessionID == "" { if sessionID == "" {
panic("empty session ID") panic("empty session ID")
} }
b.tabQueue <- sessionID b.tabQueue <- newTab{targetID, sessionID}
return <-b.tabResult return <-b.tabResult
} }
@ -231,13 +239,14 @@ func (b *Browser) run(ctx context.Context) {
pages := make(map[target.SessionID]*Target, 1024) pages := make(map[target.SessionID]*Target, 1024)
for { for {
select { select {
case sessionID := <-b.tabQueue: case tab := <-b.tabQueue:
if _, ok := pages[sessionID]; ok { if _, ok := pages[tab.sessionID]; ok {
b.errf("executor for %q already exists", sessionID) b.errf("executor for %q already exists", tab.sessionID)
} }
t := &Target{ t := &Target{
browser: b, browser: b,
SessionID: sessionID, TargetID: tab.targetID,
SessionID: tab.sessionID,
eventQueue: make(chan *cdproto.Message, 1024), eventQueue: make(chan *cdproto.Message, 1024),
waitQueue: make(chan func(cur *cdp.Frame) bool, 1024), waitQueue: make(chan func(cur *cdp.Frame) bool, 1024),
@ -247,7 +256,7 @@ func (b *Browser) run(ctx context.Context) {
errf: b.errf, errf: b.errf,
} }
go t.run(ctx) go t.run(ctx)
pages[sessionID] = t pages[tab.sessionID] = t
b.tabResult <- t b.tabResult <- t
case event := <-tabEventQueue: case event := <-tabEventQueue:
page, ok := pages[event.sessionID] page, ok := pages[event.sessionID]

View File

@ -115,7 +115,7 @@ func (c *Context) newSession(ctx context.Context, first bool) error {
if err != nil { if err != nil {
return err return err
} }
c.Target = c.Browser.newExecutorForTarget(ctx, sessionID) c.Target = c.Browser.newExecutorForTarget(ctx, targetID, sessionID)
// enable domains // enable domains
for _, enable := range []Action{ for _, enable := range []Action{

View File

@ -9,47 +9,31 @@ func TestTargets(t *testing.T) {
t.Parallel() t.Parallel()
// Start one browser with one tab. // Start one browser with one tab.
ctx1, cancel := NewContext(context.Background()) ctx1, cancel1 := NewContext(context.Background())
defer cancel() defer cancel1()
if err := Run(ctx1); err != nil { if err := Run(ctx1); err != nil {
t.Fatal(err) t.Fatal(err)
} }
{ wantTargets := func(ctx context.Context, want int) {
infos, err := Targets(ctx1) infos, err := Targets(ctx)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if want, got := 1, len(infos); want != got { if got := len(infos); want != got {
t.Fatalf("want %d targets, got %d", want, got) t.Fatalf("want %d targets, got %d", want, got)
} }
} }
wantTargets(ctx1, 1)
// Start a second tab on the same browser // Start a second tab on the same browser.
ctx2, cancel := NewContext(ctx1) ctx2, cancel2 := NewContext(ctx1)
defer cancel() defer cancel2()
if err := Run(ctx2); err != nil { if err := Run(ctx2); err != nil {
t.Fatal(err) t.Fatal(err)
} }
wantTargets(ctx2, 2)
{
infos, err := Targets(ctx2)
if err != nil {
t.Fatal(err)
}
if want, got := 2, len(infos); want != got {
t.Fatalf("want %d targets, got %d", want, got)
}
}
// The first context should also see both targets. // The first context should also see both targets.
{ wantTargets(ctx1, 2)
infos, err := Targets(ctx1)
if err != nil {
t.Fatal(err)
}
if want, got := 2, len(infos); want != got {
t.Fatalf("want %d targets, got %d", want, got)
}
}
} }

View File

@ -21,6 +21,7 @@ import (
type Target struct { type Target struct {
browser *Browser browser *Browser
SessionID target.SessionID SessionID target.SessionID
TargetID target.ID
waitQueue chan func(cur *cdp.Frame) bool waitQueue chan func(cur *cdp.Frame) bool
eventQueue chan *cdproto.Message eventQueue chan *cdproto.Message